package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasPrintTemplateEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FundAccountFlowTypeEnum;
import com.xbongbong.paas.enums.OtherExpenseSheetTypeEnum;
import com.xbongbong.paas.enums.OtherIncomeSheetTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.dto.ButtonGetDTO;
import com.xbongbong.paas.pojo.dto.PaymentExplainDTO;
import com.xbongbong.paas.pojo.dto.PaymentSheetDataDTO;
import com.xbongbong.paas.pojo.dto.PaymentSheetExplainsDTO;
import com.xbongbong.paas.pojo.dto.PaymentSheetExplainsSingleDTO;
import com.xbongbong.paas.pojo.vo.ButtonGetVO;
import com.xbongbong.paas.print.model.PaasPrintTemplateModel;
import com.xbongbong.paas.script.help.ScriptHelper;
import com.xbongbong.paas.script.pojo.FundAccountExplainsDTO;
import com.xbongbong.paas.script.pojo.dto.InitCustomerStatementDTO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.PrintSpecialAttrEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetUpdateBatchDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetUpdateDTO;
import com.xbongbong.pro.payplansheet.pojo.dto.PaySheetUpdateBatchDTO;
import com.xbongbong.pro.payplansheet.pojo.dto.PaySheetUpdateDTO;
import com.xbongbong.pro.purchase.pojo.dto.PurchaseInvoiceRepairAmountDTO;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CustomerStatementEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.FundAccountEntity;
import com.xbongbong.saas.domain.entity.FundAccountFlowEntity;
import com.xbongbong.saas.domain.entity.FundTransferEntity;
import com.xbongbong.saas.domain.entity.OtherExpenseEntity;
import com.xbongbong.saas.domain.entity.OtherIncomeEntity;
import com.xbongbong.saas.domain.entity.PayBalanceUserEntity;
import com.xbongbong.saas.domain.entity.PaymentBalanceUserEntity;
import com.xbongbong.saas.domain.entity.SupplierUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.RefundEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.CustomerStatementEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.FundTransferEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.enums.business.OtherIncomeEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.RedPaymentSheetEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerStatementModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.FundAccountFlowModel;
import com.xbongbong.saas.model.FundAccountModel;
import com.xbongbong.saas.model.FundTransferModel;
import com.xbongbong.saas.model.OtherExpenseModel;
import com.xbongbong.saas.model.OtherIncomeModel;
import com.xbongbong.saas.model.PayBalanceUserModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PaymentBalanceUserModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.SupplierUserModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.FundFixDataService;
import com.xbongbong.saas.service.PayPlanSheetService;
import com.xbongbong.saas.service.PaymentSheetService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 资金脚本
 *
 * @author 徐俊杰
 * @version v1.0
 * @date 2019/12/17 11:09
 * @since v1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/fund")
public class FundScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(FundScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private RefundModel refundModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private FundAccountModel fundAccountModel;
    @Resource
    private FundAccountFlowModel fundAccountFlowModel;
    @Resource
    private ScriptHelper scriptHelper;
    @Resource
    private PaymentSheetService paymentSheetService;
    @Resource
    private PayPlanSheetService payPlanSheetService;
    @Resource
    private FundFixDataService fundFixDataService;
    @Resource
    private PaasPrintTemplateModel paasPrintTemplateModel;
    @Resource
    private CustomerStatementModel customerStatementModel;
    @Resource
    private PaymentBalanceUserModel paymentBalanceUserModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private PayBalanceUserModel payBalanceUserModel;
    @Resource
    private SupplierUserModel supplierUserModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private OtherIncomeModel otherIncomeModel;
    @Resource
    private OtherExpenseModel otherExpenseModel;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private FundTransferModel fundTransferModel;

    /**
     * 更新回款单、退货退款、发票解释的脚本（所有公司）
     *
     * @param paymentSheetExplainsDTO 入参（校验码）
     * @return java.lang.String
     * @throws Exception 异常
     * @author 徐俊杰
     * @date 2019/12/18 9:32
     * @since v1.0
     */
    @RequestMapping(value = "/paymentSheet/explains", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String explains(@RequestBody @Valid PaymentSheetExplainsDTO paymentSheetExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            //获取未删除的公司数量
            Map<String, Object> companyParam = new HashMap<>(1);
            companyParam.put("del", BasicConstant.ZERO);
            Integer companyCount = companyModel.getEntitysCount(companyParam);
            //分步对公司批量处理
            Integer pageSize = 500;
            List<Integer> businessTypes = paymentSheetExplainsDTO.getBusinessTypes();
            List<XbbRefTypeEnum> updateXbbRefEnum = new ArrayList<>();
            businessTypes.forEach(e -> updateXbbRefEnum.add(XbbRefTypeEnum.getByCode(e)));
            //获取解释需要更新的值
            for (XbbRefTypeEnum xbbRefTypeEnum : updateXbbRefEnum) {
                List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(xbbRefTypeEnum.getAlias(),null, null, 0);
                String fieldAttrStr = JSON.toJSONString(fieldAttrEntities);
                for (int i = 0; i < companyCount; i += pageSize) {
                    //分步获取公司id集合
                    Set<String> corpidSet = getCorpidSetbyStep(i, pageSize);
                    if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                        break;
                    }
                    //获取回款单的表单解释列表
                    List<PaasFormExplainEntity> formExplainList = scriptHelper.findExplainByCorpidSet(xbbRefTypeEnum.getCode(), corpidSet);
                    //更新解释
                    formExplainList.forEach(item -> item.setExplains(fieldAttrStr));
//                    paasFormExplainModel.updateBatchExplains(formExplainList, corpid);
                    LOG.warn("处理进度" + i + "/" + companyCount);
                }
            }
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 更新应收款解释的脚本（所有公司）
     *
     * @param paymentExplainDTO 入参（校验码）]
     * @return java.lang.String
     * @throws Exception 异常
     * @author 徐俊杰
     * @date 2019/12/18 9:32
     * @since v1.0
     */
    @RequestMapping(value = "/payment/explains", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initPaymentExplains(@RequestBody @Valid PaymentExplainDTO paymentExplainDTO) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(paymentExplainDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        try {
            //获取未删除的公司数量
            Map<String, Object> companyParam = new HashMap<>(1);
            companyParam.put("del", BasicConstant.ZERO);
            Integer companyCount = companyModel.getEntitysCount(companyParam);
            //分步对公司批量处理
            Integer pageSize = 1000;
            List<Integer> businessTypes = paymentExplainDTO.getBusinessTypes();
            List<XbbRefTypeEnum> updateXbbRefEnum = new ArrayList<>();
            businessTypes.forEach(e -> updateXbbRefEnum.add(XbbRefTypeEnum.getByCode(e)));
            //获取解释需要更新的值
            for (XbbRefTypeEnum xbbRefTypeEnum : updateXbbRefEnum) {
                List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(xbbRefTypeEnum.getAlias(), null, null, 0);
                String fieldAttrStr = JSON.toJSONString(fieldAttrEntities);
                for (int i = 0; i < companyCount; i += pageSize) {
                    //分步获取公司id集合
                 Set<String> corpidSet = getCorpidSetbyStep(i, pageSize);
                 if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                     break;
                 }
                 //获取表单解释列表
                    List<PaasFormExplainEntity> formExplainList = scriptHelper.findExplainByCorpidSet(xbbRefTypeEnum.getCode(), corpidSet);
                 //更新解释
                    formExplainList.forEach(item -> item.setExplains(fieldAttrStr));
                    paasFormExplainModel.updateBatchExplains(formExplainList);
                    LOG.warn("处理进度" + i + "/" + companyCount);
                    }
                }
            } catch (Exception e) {
                LOG.error("paymentSheetExplainsError", e);
            }
            LOG.warn("-----------处理完毕-----------");
            return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/paymentSheet/explains/specify", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String explainsSpecify(@RequestBody @Valid PaymentSheetExplainsDTO paymentSheetExplainsDTO, BindingResult br) throws Exception {
        try {
            //获取解释需要更新的值
            List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(XbbRefTypeEnum.PAYMENT_SHEET.getAlias(),null, null, 0);
            String fieldAttrStr = JSON.toJSONString(fieldAttrEntities);
            List<String> corpidList = paymentSheetExplainsDTO.getCorpidList();
            //获取回款单的表单解释列表
            List<PaasFormExplainEntity> formExplainList = scriptHelper.findExplainByCorpidSet(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpidList);
            //更新解释
            formExplainList.forEach(item -> item.setExplains(fieldAttrStr));
//            paasFormExplainModel.updateBatchExplains(formExplainList, corpid);
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        return null;
    }

    @RequestMapping(value = "/paymentSheet/explains/single", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String explainsSingle(@RequestBody @Valid PaymentSheetExplainsSingleDTO paymentSheetExplainsSingleDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsSingleDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            //获取未删除的公司数量
            Map<String, Object> companyParam = new HashMap<>(1);
            companyParam.put("del", BasicConstant.ZERO);
            Integer companyCount = companyModel.getEntitysCount(companyParam);
            //分步对公司批量处理
            Integer pageSize = 500;
            //获取解释需要更新的值
            XbbRefTypeEnum paymentSheetEnum = XbbRefTypeEnum.PAYMENT_SHEET;
            XbbRefTypeEnum paymentEnum = XbbRefTypeEnum.PAYMENT;
            List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(paymentSheetEnum.getAlias(),null, null, 0);
            String fieldAttrStr = JSON.toJSONString(fieldAttrEntities);
            for (int i = 0; i < companyCount; i += pageSize) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(i, pageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                //回款单的表单解释列表
                List<PaasFormExplainEntity> paymentSheetFormExplainList = scriptHelper.findExplainByCorpidSet(paymentSheetEnum.getCode(), corpidSet);
                //应收款表单解释列表
                List<PaasFormExplainEntity> paymentFormExplainList = scriptHelper.findExplainByCorpidSet(paymentEnum.getCode(), corpidSet);
                //公司id-支付方式map
                Map<String, List<ItemPoJo>> corpidPaymentMethodMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for (PaasFormExplainEntity paymentExplainEntity : paymentFormExplainList) {
                    String corpid = paymentExplainEntity.getCorpid();
                    //应收款字段列表
                    List<FieldAttrEntity> paymentExplainList = JSONArray.parseArray(paymentExplainEntity.getExplains(), FieldAttrEntity.class);
                    for (FieldAttrEntity fieldAttrEntity : paymentExplainList) {
                        String attr = fieldAttrEntity.getAttr();
                        //应收款支付方式字段
                        if (Objects.equals(PaymentEnum.PAYMENT_METHOD.getAttr(), attr)) {
                            List<ItemPoJo> items = fieldAttrEntity.getItems();
                            corpidPaymentMethodMap.put(corpid, items);
                        }
                    }
                }
                for (PaasFormExplainEntity paymentSheetExplainEntity : paymentSheetFormExplainList) {
                    //1 更新成默认的解释
                    paymentSheetExplainEntity.setExplains(fieldAttrStr);
                    String corpid = paymentSheetExplainEntity.getCorpid();
                    List<ItemPoJo> itemPoJos = corpidPaymentMethodMap.get(corpid);
                    if (CollectionsUtil.isEmpty(itemPoJos)) {
                        continue;
                    }
                    //2 单独处理回款单的支付方式字段
                    List<FieldAttrEntity> paymentSheetExplainList = JSONArray.parseArray(paymentSheetExplainEntity.getExplains(), FieldAttrEntity.class);
                    for (FieldAttrEntity fieldAttrEntity : paymentSheetExplainList) {
                        String attr = fieldAttrEntity.getAttr();
                        if (Objects.equals(PaymentSheetEnum.PAY_METHOD.getAttr(), attr)) {
                            fieldAttrEntity.setItems(itemPoJos);
                        }
                    }
                    String paymentSheetExplains = JSON.toJSONString(paymentSheetExplainList);
                    paymentSheetExplainEntity.setExplains(paymentSheetExplains);
                }
                //更新解释
//                paasFormExplainModel.updateBatchExplains(paymentSheetFormExplainList, corpid);
                LOG.warn("处理进度" + i + "/" + companyCount);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/paymentSheet/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String data(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, BindingResult br) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            Integer companyCount = scriptHelper.getCompanyCount();
            //分步查公司id，一次查1000条
            int corpPageSize = 500;
            //分步查回款单，一次查100条（查客户的terms的长度最大值等于这个条数）
            int paymentSheetPageSize = 100;
            Map<String, Object> paymentSheetMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paymentSheetMap.put("pageNum", paymentSheetPageSize);
            paymentSheetMap.put("del", BasicConstant.ZERO);
            for (int t = 0; t < companyCount; t += corpPageSize) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(t, corpPageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                List<String> excludeCorpidList = paymentSheetDataDTO.getExcludeCorpidList();
                if (!Objects.isNull(excludeCorpidList)) {
                    corpidSet.removeAll(excludeCorpidList);
                }
                //每家公司单独处理
                for (String corpid : corpidSet) {
                    try {
                        //更新回款单数据的formId和menuId
                        int businessType = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
                        String columns = "id, menu_id";
                        PaasFormEntityExt formEntity = paasFormModel.getByBusinessType(businessType, corpid, columns);
                        if (formEntity == null) {
                            continue;
                        }
                        Long menuId = formEntity.getMenuId();
                        Long formId = formEntity.getId();
                        paymentSheetMap.put("corpid", corpid);
                        //暂时一个公司内一起处理，如果红冲回款过多，可以考虑分步
                        Map<Long, Long> redIdOldIdMap = new HashMap<>(16);
                        for (int i = 0; ; i += paymentSheetPageSize) {
                            paymentSheetMap.put("start", i);
                            List<PaymentSheetEntityExt> paymentSheetList = paymentSheetModel.findEntitys(paymentSheetMap);
                            //如果数据为空则跳出循环
                            if (paymentSheetList.isEmpty()) {
                                break;
                            }
                            Set<Long> paymentIdSet = new HashSet<>(paymentSheetList.size());
                            getAssociatedConditions(paymentSheetList, paymentIdSet, redIdOldIdMap);
                            //包装应收款关联关系
                            Map<Long, String> paymentIdSerialNoMap = new HashMap<>(paymentIdSet.size());
                            Map<Long, JSONObject> paymentIdDataMap = new HashMap<>(paymentIdSet.size());
                            getPaymentInfo(corpid, paymentIdSet, paymentIdSerialNoMap, paymentIdDataMap);
                            List<PaymentSheetEntityExt> packagePaymentSheetList = new ArrayList<>(paymentSheetList.size());
                            //处理字段
                            disposeField(paymentSheetList, paymentIdSerialNoMap, packagePaymentSheetList, paymentIdDataMap, menuId, formId);
//                            paymentSheetModel.updateBatchForAll(packagePaymentSheetList, corpid, false);
                        }
                        disposeRedIdOldId(redIdOldIdMap, corpid);
                    } catch (Exception e) {
                        LOG.error("FundScriptController.processData corpid===" + corpid, e);
                    }
                }
                LOG.warn("处理进度" + t + "/" + companyCount);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetScriptError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 处理退货生成的回款单（现在线上这种回款单关联的合同id其实是退货退款id）
     * @param paymentSheetDataDTO
     * @param br
     * @return java.lang.String
     * @throws Exception
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/paymentSheet/redData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String redData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, BindingResult br) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            Integer companyCount = scriptHelper.getCompanyCount();
            //分步查公司id，一次查1000条
            int corpPageSize = 500;
            //分步查回款单，一次查100条（查客户的terms的长度最大值等于这个条数）
            int paymentSheetPageSize = 100;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("pageNum", paymentSheetPageSize);
            param.put("isRed", BasicConstant.ONE);
            param.put("refType", XbbRefTypeEnum.REFUND.getCode());
            for (int t = 0; t < companyCount; t += corpPageSize) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(t, corpPageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                List<String> excludeCorpidList = paymentSheetDataDTO.getExcludeCorpidList();
                if (!Objects.isNull(excludeCorpidList)) {
                    corpidSet.removeAll(excludeCorpidList);
                }
                //每家公司单独处理
                for (String corpid : corpidSet) {
                    try {
                        param.put("corpid", corpid);
                        for (int i = 0; ; i += paymentSheetPageSize) {
                            param.put("start", i);
                            List<PaymentEntityExt> paymentList = paymentModel.findEntitys(param);
                            //如果数据为空则跳出循环
                            if (paymentList.isEmpty()) {
                                break;
                            }
                            Set<Long> paymentIdSet = new HashSet<>();
                            Set<Long> refundIdSet = new HashSet<>();
                            //红冲应收款id-退货退款id
                            Map<Long, Long> redPlanIdRefundIdMap = new HashMap<>();
                            for (PaymentEntityExt entityExt : paymentList) {
                                paymentIdSet.add(entityExt.getId());
                                JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
                                String refundIdStr = data.getString(PaymentEnum.CONTRACT.getAttr());
                                if (StringUtil.isNotEmpty(refundIdStr)) {
                                    Long refundId = StringUtil.StringToLong(refundIdStr);
                                    refundIdSet.add(refundId);
                                    redPlanIdRefundIdMap.put(entityExt.getId(), refundId);
                                }
                            }
                            if (refundIdSet.size() == 0) {
                                continue;
                            }
                            //此时查处的回款单都为
                            List<PaymentSheetEntityExt> sheetList = getRedSheetList(corpid, paymentIdSet);
                            if (sheetList.size() == 0) {
                                continue;
                            }
                            //退货退款id-退款data
                            Map<Long, JSONObject> refundIdDataMap = getRefundInfo(corpid, refundIdSet);
                            List<PaymentSheetEntityExt> paymentSheetList = new ArrayList<>();
                            for (PaymentSheetEntityExt entityExt : sheetList) {
                                JSONObject data = entityExt.getData();
                                if (data == null) {
                                    continue;
                                }
                                JSONArray payment = data.getJSONArray(PaymentSheetEnum.PAYMENT.getAttr());
                                if (payment == null || payment.size() == 0 || payment.size() > 1) {
                                    //只处理关联了一个应收款的（只有改版后才能关联多个）
                                    continue;
                                }
                                Long redPaymentId = payment.getLongValue(0);
                                Long refundId = redPlanIdRefundIdMap.get(redPaymentId);
                                if (refundId == null) {
                                    continue;
                                }
                                JSONObject refundData = refundIdDataMap.get(refundId);
                                if (refundData == null) {
                                    continue;
                                }
                                String contractIdStr = refundData.getString(RefundEnum.CONTRACT_ID.getAttr());
                                Long contractId = StringUtil.StringToLong(contractIdStr);
                                if (contractId != null) {
                                    String contractName = refundData.getString(RefundEnum.CONTRACT_ID_LINKED_TEXT.getAttr());
                                    JSONArray idArray = new JSONArray();
                                    idArray.add(contractId);
                                    JSONArray nameArray = new JSONArray();
                                    nameArray.add(contractName);
                                    data.put(PaymentSheetEnum.CONTRACT.getAttr(), idArray);
                                    data.put(PaymentSheetEnum.CONTRACT_LINK_TEXT.getAttr(), nameArray);
                                    PaymentSheetEntityExt paymentSheet = new PaymentSheetEntityExt();
                                    BeanUtil.copyProperties(entityExt, paymentSheet);
                                    paymentSheet.setData(data);
                                    paymentSheetList.add(paymentSheet);
                                }
                            }
                            if (paymentSheetList.size() > 0) {
//                                paymentSheetModel.updateBatchForAll(paymentSheetList, corpid, false);
                            }
                        }
                    } catch (Exception e) {
                        LOG.error("FundScriptController.redData corpid===" + corpid, e);
                    }
                }
                LOG.warn("处理进度" + t + "/" + companyCount);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetScriptError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/paymentSheet/data/specify", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String dataSpecify(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, BindingResult br) throws Exception {
        try {
            int paymentSheetPageSize = 100;
            List<String> corpidList = paymentSheetDataDTO.getCorpidList();
            Map<String, Object> paymentSheetMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paymentSheetMap.put("pageNum", paymentSheetPageSize);
            for (String corpid : corpidList) {
                //更新回款单数据的formId和menuId
                int businessType = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
                String columns = "id, menu_id";
                PaasFormEntityExt formEntity = paasFormModel.getByBusinessType(businessType, corpid, columns);
                Long menuId = formEntity.getMenuId();
                Long formId = formEntity.getId();
                paymentSheetMap.put("corpid", corpid);
                //暂时一个公司内一起处理，如果红冲回款过多，可以考虑分步
                Map<Long, Long> redIdOldIdMap = new HashMap<>(16);
                for (int i = 0; ; i += paymentSheetPageSize) {
                    paymentSheetMap.put("start", i);
                    List<PaymentSheetEntityExt> paymentSheetList = paymentSheetModel.findEntitys(paymentSheetMap);
                    //如果数据为空则跳出循环
                    if (paymentSheetList.isEmpty()) {
                        break;
                    }
                    Set<Long> paymentIdSet = new HashSet<>(paymentSheetList.size());
                    getAssociatedConditions(paymentSheetList, paymentIdSet, redIdOldIdMap);
                    //包装应收款关联关系
                    Map<Long, String> paymentIdSerialNoMap = new HashMap<>(paymentIdSet.size());
                    Map<Long, JSONObject> paymentIdDataMap = new HashMap<>(paymentIdSet.size());
                    getPaymentInfo(corpid, paymentIdSet, paymentIdSerialNoMap, paymentIdDataMap);
                    List<PaymentSheetEntityExt> packagePaymentSheetList = new ArrayList<>(paymentSheetList.size());
                    //处理字段
                    disposeField(paymentSheetList, paymentIdSerialNoMap, packagePaymentSheetList, paymentIdDataMap, menuId, formId);
                    try {
//                        paymentSheetModel.updateBatchForAll(packagePaymentSheetList, corpid, false);
                    } catch (Exception e) {
                        LOG.error("paymentSheetScriptError", e);
                    }
                }
                disposeRedIdOldId(redIdOldIdMap, corpid);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetScriptError", e);
        }
        return null;
    }

    /**
     * 审批中回款单数据处理
     * @param paymentSheetDataDTO
     * @param br
     * @return java.lang.String
     * @throws Exception
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/paymentSheet/process/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String processData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, BindingResult br) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            List<String> corpidList = paymentSheetDataDTO.getCorpidList();
            //分步查回款单，一次查100条（查客户的terms的长度最大值等于这个条数）
            int paymentSheetPageSize = 100;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("pageNum", paymentSheetPageSize);
            param.put("saasMark", SaasMarkEnum.SAAS.getCode());
            param.put("businessType", XbbRefTypeEnum.PAYMENT_SHEET.getCode());
            param.put("del", BasicConstant.ZERO);
            if (corpidList != null && corpidList.size() > 0) {
                //该值不为空，则代表刷特定的公司（防止一些公司数据处理错误，需要重新刷的情况）
                handleProcessData(paymentSheetDataDTO, paymentSheetPageSize, param, new HashSet<>(corpidList));
                LOG.warn("-----------特定公司数据处理完毕，共处理了" + corpidList.size() + "个公司的数据-----------");
                return JSON.toJSONString("{\"msg\":\"特定公司数据处理完毕\"}");
            }
            //分步查公司id，一次查1000条
            int corpPageSize = 1000;
            Integer companyCount = scriptHelper.getCompanyCount();
            for (int t = 0; t < companyCount; t += corpPageSize) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(t, corpPageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                handleProcessData(paymentSheetDataDTO, paymentSheetPageSize, param, corpidSet);
                LOG.warn("审批中数据处理进度" + t + "/" + companyCount);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetScriptError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/refund/fix/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRefundDataInProcess(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, BindingResult br) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> idIn = new ArrayList<>();
            idIn.add(229310L);
            idIn.add(234322L);
            idIn.add(234412L);
            idIn.add(234677L);
            idIn.add(239383L);
            param.put(StringConstant.IDIN, idIn);
            List<PaasProcessDataEntity> list = paasProcessDataModel.list(param);
            List<String> corpidList = paymentSheetDataDTO.getCorpidList();
            String corpid = corpidList.get(0);
            list.forEach(e -> {
                String dataStr = e.getData();
                JSONObject data = JSON.parseObject(dataStr);
                JSONArray paymentJsonArray = data.getJSONArray(RefundEnum.PAYMENT_SHEETS.getAttr());
                for (Object paymentObj : paymentJsonArray) {
                    JSONObject jsonObject = (JSONObject) paymentObj;
                    //回款单ID
                    Long id = jsonObject.getLong("id");
                    if (Objects.nonNull(id)) {
                        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid);
                        ButtonGetDTO buttonGetDTO = new ButtonGetDTO();
                        BeanUtil.copyProperties(paasFormEntityExt, buttonGetDTO);
                        buttonGetDTO.setDataIdIn(Arrays.asList(id));
                        buttonGetDTO.setBusinessType(XbbRefTypeEnum.RED_PAYMENT_SHEET.getCode());
                        try {
                            ButtonGetVO buttonGetVO = paasFormDataService.buttonGet(buttonGetDTO);
                            PaasFormDataEntityExt dataEntityExt = buttonGetVO.getDataList().get(0);
                            JSONObject resultData = dataEntityExt.getData();
                            resultData.put("id", id);
                            JSONArray jsonArray = new JSONArray();
                            jsonArray.add(jsonObject);
                            resultData.put(PaymentSheetEnum.RED_SHEET.getAttr(), jsonArray);
                            resultData.put("name", dataEntityExt.getSerialNo());
                            resultData.put("appId", buttonGetDTO.getAppId());
                            resultData.put("formId", buttonGetDTO.getFormId());
                            resultData.put("menuId", buttonGetDTO.getMenuId());
                            resultData.put("dataId", id);
                            JSONArray newJsonArray = new JSONArray();
                            newJsonArray.add(resultData);
                            data.put(RefundEnum.PAYMENT_SHEETS.getAttr(), newJsonArray);
                            String resultStr = JSON.toJSONString(data);
                            e.setData(resultStr);
                            paasProcessDataModel.update(e);
                            LOG.warn("审批中数据ID：" + e.getId() + "--处理完毕");
                        } catch (Exception ex) {
                            LOG.warn(ex.getMessage());
                        }
                    }
                }
            });
        } catch (Exception e) {
            LOG.error("paymentSheetScriptError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 更新公司审批数据
     * @param paymentSheetDataDTO 刷回款单数据dto
     * @param paymentSheetPageSize 步长
     * @param param 参数
     * @param corpidSet 要更新的corpid集合
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void handleProcessData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO, int paymentSheetPageSize, Map<String, Object> param, Set<String> corpidSet) {
        List<String> excludeCorpidList = paymentSheetDataDTO.getExcludeCorpidList();
        if (!Objects.isNull(excludeCorpidList)) {
            corpidSet.removeAll(excludeCorpidList);
        }
        //每家公司单独处理
        for (String corpid : corpidSet) {
            try {
                //更新回款单数据的formId和menuId
                int businessType = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
                String columns = "id, menu_id";
                PaasFormEntityExt formEntity = paasFormModel.getByBusinessType(businessType, corpid, columns);
                if (formEntity == null) {
                    continue;
                }
                Long menuId = formEntity.getMenuId();
                Long formId = formEntity.getId();
                param.put("corpid", corpid);
                //暂时一个公司内一起处理，如果红冲回款过多，可以考虑分步
                Map<Long, Long> redIdOldIdMap = new HashMap<>(16);
                for (int i = 0; ; i += paymentSheetPageSize) {
                    param.put("start", i);
                    List<PaasProcessDataEntity> processDataEntityList = paasProcessDataModel.list(param);
                    //如果数据为空则跳出循环
                    if (processDataEntityList.isEmpty()) {
                        break;
                    }
                    int size = processDataEntityList.size();
                    Set<Long> paymentIdSet = new HashSet<>(size);
                    for (PaasProcessDataEntity paasProcessDataEntity : processDataEntityList) {
                        JSONObject data = JSON.parseObject(paasProcessDataEntity.getData());
                        scriptHelper.getAssociatedConditions4Data(paymentIdSet, data, PaymentSheetEnum.PAYMENT.getAttr(), PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr());
                        paasProcessDataEntity.setData(JSONObject.toJSONString(data));
                    }
                    //包装应收款关联关系
                    Map<Long, String> paymentIdSerialNoMap = new HashMap<>(paymentIdSet.size());
                    Map<Long, JSONObject> paymentIdDataMap = new HashMap<>(paymentIdSet.size());
                    getPaymentInfo(corpid, paymentIdSet, paymentIdSerialNoMap, paymentIdDataMap);
                    List<PaasProcessDataEntity> packageList = new ArrayList<>();
                    //处理字段
                    for (PaasProcessDataEntity paasProcessDataEntity : processDataEntityList) {
                        paasProcessDataEntity.setMenuId(menuId);
                        paasProcessDataEntity.setFormId(formId);
                        JSONObject data = JSON.parseObject(paasProcessDataEntity.getData());
                        //处理编号（serial_no）
                        String serialNo = data.getString("text_1");
                        if (StringUtil.isNotEmpty(serialNo)) {
                            paasProcessDataEntity.setSerialNo(serialNo);
                        }
                        //处理关联原始回款单id
                        Integer ifRed = data.getInteger("num_3");
                        if (Objects.equals(ifRed, BasicConstant.ONE)) {
                            String linkOldSheetStr = data.getString(RedPaymentSheetEnum.LINK_SHEET.getAttr());
                            if (StringUtil.isNotEmpty(linkOldSheetStr) && linkOldSheetStr.startsWith(ChartConstant.LEFT_PARENTHESES)) {
                                JSONArray linkOldSheet = data.getJSONArray(RedPaymentSheetEnum.LINK_SHEET.getAttr());
                                if (linkOldSheet != null && linkOldSheet.size() > 0) {
                                    JSONObject jsonObject = linkOldSheet.getJSONObject(0);
                                    if (jsonObject != null) {
                                        data.put(PaymentSheetEnum.RED_SHEET.getAttr(), jsonObject.getLong(BasicConstant.ID));
                                        data.put(PaymentSheetEnum.RED_SHEET_LINK_TEXT.getAttr(), jsonObject.getString(BasicConstant.NAME));
                                    }
                                }
                            }
                        }
                        disposeFieldByData(paymentIdSerialNoMap, paymentIdDataMap, data);
                        paasProcessDataEntity.setData(JSONObject.toJSONString(data));
                        packageList.add(paasProcessDataEntity);
                    }
                    paasProcessDataModel.updateBatchForAll(packageList, corpid);
                }
                disposeRedIdOldId(redIdOldIdMap, corpid);
            } catch (Exception e) {
                LOG.error("FundScriptController.handleProcessData corpid===" + corpid, e);
            }
        }
    }

    /**
     * 获取回款单的关联数据并放入集合中
     *
     * @param paymentSheetList 回款单列表
     * @param paymentIdSet 应收款id集合
     * @param redIdOldIdMap 红冲回款单id-原回款单id-map
     * @author 徐俊杰
     * @date 2019/12/19 16:15
     * @since v1.0
     */
    private void getAssociatedConditions(List<PaymentSheetEntityExt> paymentSheetList, Set<Long> paymentIdSet,
                                         Map<Long, Long> redIdOldIdMap) {
        /*
         非审批中数据，封装红冲回款单id和原单id对应关系需要依赖原单（原数据结构是把红冲id关联到原单上面）
         审批中数据，直接使用text_8读取关联原始回款单id(RedPaymentSheetEnum内的text_8即关联原单id）
         */
        for (PaasFormDataEntity dataEntity : paymentSheetList) {
            JSONObject data = dataEntity.getData();
            Long id = dataEntity.getId();
            //红冲回款单id
            Long redId = data.getLong("num_4");
            if (redId != null && !Objects.equals(redId, 0L)) {
                redIdOldIdMap.put(redId, id);
            }
            scriptHelper.getAssociatedConditions4Data(paymentIdSet, data, PaymentSheetEnum.PAYMENT.getAttr(), PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr());
        }
    }

    /**
     * 读取过后直接存入为数组格式
     * @param data 数据data
     * @param linkAttr 关联attr
     * @param linkHideAttr 关联业务隐藏
     * @return java.lang.Long
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private Long getLinkId4Arr(JSONObject data, String linkAttr, String linkHideAttr) {
        String linkIdStr = data.getString(linkAttr);
        Long linkId = -1L;
        try {
            linkId = Long.parseLong(linkIdStr);
        } catch (NumberFormatException e) {
            JSONArray jsonArray = JSONArray.parseArray(linkIdStr);
            if (jsonArray != null && jsonArray.size() > 0) {
                Object object = jsonArray.get(0);
                if (object instanceof Long) {
                    linkId = jsonArray.getLong(0);
                } else if (object instanceof String) {
                    linkId = StringUtil.StringToLong(jsonArray.getString(0));
                } else if (object instanceof JSONObject) {
                    JSONObject jsonObject = jsonArray.getJSONObject(0);
                    linkId = jsonObject.getLong(StringConstant.SAAS_LINK_BUSINESS_ID);
                    JSONArray idArray = new JSONArray();
                    idArray.add(linkId);
                    JSONArray noArray = new JSONArray();
                    noArray.add(jsonObject.getString(StringConstant.SAAS_LINK_BUSINESS_NAME));
                    data.put(linkAttr, idArray);
                    data.put(linkHideAttr, noArray);
                }
            }
        }
        return linkId;
    }

    /**
     * 客户id-客户名称-map
     *
     * @param corpid 公司id
     * @param customerIdSet 客户id集合
     * @param customerIdNameMap 客户id-客户名称-map
     * @throws XbbException 获取customerList时的异常
     * @author 徐俊杰
     * @date 2019/12/19 16:21
     * @since v1.0
     */
    private void getCustomerInfo(String corpid, Set<Long> customerIdSet, Map<Long, String> customerIdNameMap) throws XbbException {
        //查询客户名称
        Map<String, Object> customerParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        customerParam.put("corpid", corpid);
        customerParam.put("idIn", customerIdSet);
        List<CustomerEntityExt> customerList = customerModel.findEntitys(customerParam);
        //包装客户id-客户名称map
        for (PaasFormDataEntity customer : customerList) {
            JSONObject customerData = customer.getData();
            String customerName = customerData.getString(CustomerManagementEnum.NAME.getAttr());
            if (customerName == null) {
                continue;
            }
            Long customerId = customer.getId();
            customerIdNameMap.put(customerId, customerName);
        }
    }

    /**
     * 1.退货退款关联合同的id集合
     * 2.退货退款id-合同id-map
     *
     * @param corpid 公司id
     * @param refundIdSet 退货退款id集合
     * @param contractIdSet 合同id集合
     * @param refundIdContractIdMap 退货退款id-合同id-map
     * @throws XbbException 查询退货退款列表异常
     * @author 徐俊杰
     * @date 2019/12/19 17:02
     * @since v1.0
     */
    private void getRefundInfo(String corpid, Set<Long> refundIdSet, Set<Long> contractIdSet, Map<Long, Long> refundIdContractIdMap) throws XbbException {
        //获取退货退款关联合同id
        Map<String, Object> refundParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        refundParam.put("corpid", corpid);
        refundParam.put("idIn", refundIdSet);
        List<RefundEntityExt> refundList = refundModel.findEntitys(refundParam);
        //包装合同id集合
        //包装退货退款id-合同id-map
        for (PaasFormDataEntity refund : refundList) {
            JSONObject refundData = refund.getData();
            String contractIdStr = refundData.getString(RefundEnum.CONTRACT_ID.getAttr());
            if (contractIdStr == null) {
                continue;
            }
            Long contractId = StringUtil.StringToLong(contractIdStr, -1L);
            //退货退款关联的合同也要放入合同id集合中
            contractIdSet.add(contractId);
            Long refundId = refund.getId();
            refundIdContractIdMap.put(refundId, contractId);
        }
    }

    /**
     * 得到退货退款id和退货data的对应关系map
     * @param corpid 公司id
     * @param refundIdSet 退货退款id数组
     * @return java.util.Map<java.lang.Long,com.alibaba.fastjson.JSONObject>
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private Map<Long, JSONObject> getRefundInfo(String corpid, Set<Long> refundIdSet) {
        //获取退货退款关联合同id
        Map<String, Object> refundParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        refundParam.put("corpid", corpid);
        refundParam.put("idIn", refundIdSet);
        List<RefundEntityExt> refundList = refundModel.findEntitys(refundParam);
        //退货退款id-退货data
        Map<Long, JSONObject> refundIdDataMap = new HashMap<>(refundList.size());
        for (PaasFormDataEntity refund : refundList) {
            JSONObject refundData = JsonHelperUtil.getJSONObject(refund.getData());
            refundIdDataMap.put(refund.getId(), refundData);
        }
        return refundIdDataMap;
    }

    /**
     * 获取应收款关联回款单list：只获取2020-1-14 8点之前创建的数据（该时间点之后已经上线为新代码，不会再生成此类数据）
     * @param corpid 公司id
     * @param paymentIdSet 应收款id集合
     * @return java.util.List<com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt>
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private List<PaymentSheetEntityExt> getRedSheetList(String corpid, Set<Long> paymentIdSet) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", BasicConstant.ZERO);
        param.put("isRed", BasicConstant.ONE);
        param.put("paymentIdIn", paymentIdSet);
        //只获取2020-1-14 8点之前创建的数据（该时间点之后已经上线为新代码，不会再生成此类数据）
        Long addTime = 1578960000L;
        param.put("addTimeEnd", addTime);
        List<PaymentSheetEntityExt> list = paymentSheetModel.findEntitys(param);
        return list;
    }

    /**
     * 合同id-合同编号-map
     *
     * @param corpid 公司id
     * @param contractIdSet 合同id集合
     * @param contractIdSerialNoMap 合同id-合同编号-map
     * @throws XbbException 获取合同列表异常
     * @author 徐俊杰
     * @date 2019/12/19 17:12
     * @since v1.0
     */
    private void getContractInfo(String corpid, Set<Long> contractIdSet, Map<Long, String> contractIdSerialNoMap) throws XbbException {
        Map<String, Object> contractParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        contractParam.put("corpid", corpid);
        contractParam.put("idIn", contractIdSet);
        List<ContractEntityExt> contractList = contractModel.findEntitys(contractParam);
        //包装合同id-编号map
        for (PaasFormDataEntity contract : contractList) {
            Long id = contract.getId();
            String serialNo = contract.getSerialNo();
            contractIdSerialNoMap.put(id, serialNo);
        }
    }

    /**
     * 应收款id-应收款编号-map
     *
     * @param corpid 公司id
     * @param paymentIdSet 应收款id集合
     * @param paymentIdSerialNoMap 应收款id-应收款编号-map
     * @param paymentIdDataMap 应收款id-回款data
     * @throws XbbException 获取应收款列表时异常
     * @author 徐俊杰
     * @date 2019/12/19 17:15
     * @since v1.0
     */
    private void getPaymentInfo(String corpid, Set<Long> paymentIdSet, Map<Long, String> paymentIdSerialNoMap, Map<Long, JSONObject> paymentIdDataMap) throws XbbException {
        Map<String, Object> paymentParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paymentParam.put("corpid", corpid);
        paymentParam.put("idIn", paymentIdSet);
        List<PaymentEntityExt> paymentList = paymentModel.findEntitys(paymentParam);
        Set<Long> originPaymentIds = new HashSet<>();
        //包装合同id-编号map
        for (PaasFormDataEntity payment : paymentList) {
            Long id = payment.getId();
            JSONObject data = payment.getData();
            if (data == null) {
                data = new JSONObject();
            }
            String serialNo = payment.getSerialNo();
            paymentIdSerialNoMap.put(id, serialNo);
            data.put("planSerialNo", payment.getSerialNo());
            data.put(BasicConstant.DATAID, payment.getId());
            paymentIdDataMap.put(id, data);
            //如果关联了原始应收款，则把原始的也查出来
            String originIdStr = data.getString(PaymentEnum.ORIGIN_ID.getAttr());
            originPaymentIds.add(StringUtil.StringToLong(originIdStr));
        }
        //去除重复部分
        originPaymentIds.removeAll(paymentIdSet);
        if (originPaymentIds.size() > 0) {
            paymentParam.put("idIn", originPaymentIds);
            paymentList = paymentModel.findEntitys(paymentParam);
            //包装合同id-编号map
            for (PaasFormDataEntity payment : paymentList) {
                Long id = payment.getId();
                JSONObject data = payment.getData();
                if (data == null) {
                    data = new JSONObject();
                }
                String serialNo = payment.getSerialNo();
                paymentIdSerialNoMap.put(id, serialNo);
                data.put("planSerialNo", payment.getSerialNo());
                data.put(BasicConstant.DATAID, payment.getId());
                paymentIdDataMap.put(id, data);
            }
        }
    }

    /**
     * @param redIdOldIdMap 红冲回款单id-原回款单id-map
     * @param corpid 公司id
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/12/19 17:34
     * @since v1.0
     */
    private void disposeRedIdOldId(Map<Long, Long> redIdOldIdMap, String corpid) throws XbbException {
        //红冲回款单列表
        Set<Long> redIdSet = redIdOldIdMap.keySet();
        Map<String, Object> redParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        redParam.put("corpid", corpid);
        redParam.put("idIn", redIdSet);
        List<PaymentSheetEntityExt> redPaymentSheetList = paymentSheetModel.findEntitys(redParam);
        //原回款单列表
        Set<Long> oldIdSet = new HashSet<>(redIdOldIdMap.size());
        for (Map.Entry<Long, Long> entry : redIdOldIdMap.entrySet()) {
            Long oldId = entry.getValue();
            oldIdSet.add(oldId);
        }
        Map<String, Object> oldParam = new HashMap<> (PaasConstant.DEFAULT_INITIAL_CAPACITY);
        oldParam.put("corpid", corpid);
        oldParam.put("idIn", oldIdSet);
        List<PaymentSheetEntityExt> oldPaymentSheetList = paymentSheetModel.findEntitys(oldParam);
        //原回款单id-原回款单编号map
        Map<Long, String> oldIdSerialNoMap = new HashMap<>(oldPaymentSheetList.size());
        for (PaasFormDataEntity old : oldPaymentSheetList) {
            Long oldId = old.getId();
            String oldSerialNo = old.getSerialNo();
            oldIdSerialNoMap.put(oldId, oldSerialNo);
        }
        //更新红冲回款单的关联原回款单和关联原回款单的编号
        List<PaymentSheetEntityExt> paymentSheetList = new ArrayList<>(redPaymentSheetList.size());
        for (PaasFormDataEntity red : redPaymentSheetList) {
            Long redId = red.getId();
            Long oldId = redIdOldIdMap.get(redId);
            if (oldId == null) {
                continue;
            }
            JSONObject redData = red.getData();
            redData.put(PaymentSheetEnum.RED_SHEET.getAttr(), String.valueOf(oldId));
            String oldSerialNo = oldIdSerialNoMap.get(oldId);
            if (oldSerialNo == null) {
                continue;
            }
            redData.put(PaymentSheetEnum.RED_SHEET_LINK_TEXT.getAttr(), oldSerialNo);
            packageUpdatePaymentSheet(red, paymentSheetList);
        }
//        paymentSheetModel.updateBatchForAll(paymentSheetList, corpid, false);
    }

    /**
     * 把原回款单包装成新回款单
     *
     * @param simplePaymentSheet 原回款单
     * @param paymentSheetList 新回款单列表
     * @author 徐俊杰
     * @date 2019/12/19 17:32
     * @since v1.0
     */
    private void packageUpdatePaymentSheet(PaasFormDataEntity simplePaymentSheet, List<PaymentSheetEntityExt> paymentSheetList) {
        PaymentSheetEntityExt paymentSheet = new PaymentSheetEntityExt();
        BeanUtil.copyProperties(simplePaymentSheet, paymentSheet);
        paymentSheet.setUuid(UUID.randomUUID().toString());
        paymentSheetList.add(paymentSheet);
    }

    /**
     * 分步获取公司id集合
     *
     * @param start 开始序号
     * @param pageSize 公司个数
     * @return java.util.Set<java.lang.String>
     * @author 徐俊杰
     * @date 2019/12/19 15:54
     * @since v1.0
     */
    private Set<String> getCorpidSetbyStep(Integer start, Integer pageSize) {
        Map<String, Object> companyParam = new HashMap<>(4);
        companyParam.put("del", BasicConstant.ZERO);
        companyParam.put("pageNum", pageSize);
        companyParam.put("start", start);
        companyParam.put("columns", "corpid");
        List<CompanyEntity> companyList = companyModel.findEntitys(companyParam);
        Set<String> corpidSet = new HashSet<>();
        companyList.forEach(item -> corpidSet.add(item.getCorpid()));
        return corpidSet;
    }
    /**
     * 处理回款单列表中回款单的字段
     *
     * @param paymentSheetList 回款单列表
     * @param paymentIdSerialNoMap 应收款id-应收款编号-map
     * @param packagePaymentSheetList 需要更新的回款单列表
     * @param paymentIdDataMap 应收款id-应收款data-map
     * @author 徐俊杰
     * @date 2019/12/19 17:26
     * @since v1.0
     */
    private void disposeField(List<PaymentSheetEntityExt> paymentSheetList, Map<Long, String> paymentIdSerialNoMap, List<PaymentSheetEntityExt> packagePaymentSheetList, Map<Long, JSONObject> paymentIdDataMap, Long menuId, Long formId) {
        for (PaymentSheetEntityExt paymentSheet : paymentSheetList) {
            String uuid = paymentSheet.getUuid();
            if (!StringUtil.isEmpty(uuid)) {
                continue;
            }
            paymentSheet.setMenuId(menuId);
            paymentSheet.setFormId(formId);
            JSONObject data = paymentSheet.getData();
            //处理编号（serial_no）
            String serialNo = data.getString("text_1");
            if (StringUtil.isNotEmpty(serialNo)) {
                paymentSheet.setSerialNo(serialNo);
            }
            disposeFieldByData(paymentIdSerialNoMap, paymentIdDataMap, data);
            packageUpdatePaymentSheet(paymentSheet, packagePaymentSheetList);
        }
    }

    /**
     * 处理回款单的字段，刷为新的格式
     * @param paymentIdSerialNoMap 应收款id-应收款编号-map
     * @param paymentIdDataMap 应收款id-应收款data-map
     * @param data 数据data
     * @author 俊杰
     * @since v1.0
     * @version v1.0
     * @update 2019/12/31 by zcp 兼容普通回款单和审批中回款单字段的刷新
     */
    private void disposeFieldByData(Map<Long, String> paymentIdSerialNoMap, Map<Long, JSONObject> paymentIdDataMap, JSONObject data) {
        //处理类型字段（text_10）
        Integer ifBad = data.getInteger("num_2");
        Integer ifRed = data.getInteger("num_3");
        if (Objects.equals(ifBad, BasicConstant.ONE)) {
            data.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), PaymentSheetTypeEnum.BAD_PAYMENT.getCode());
        } else if (Objects.equals(ifRed, BasicConstant.ONE)) {
            data.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), PaymentSheetTypeEnum.RED_WRITE_OFF.getCode());
        } else {
            String paymentSheetType = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
            if (StringUtil.isNotEmpty(paymentSheetType)) {
                //回款单类型不为空，则说明已经刷过，不用再处理
                return;
            }
            data.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), PaymentSheetTypeEnum.WRITE_OFF.getCode());
        }
        //处理关联应收款（text_5）（是数组）
        String paymentIdStr = data.getString(PaymentSheetEnum.PAYMENT.getAttr());
        JSONObject planData = null;
        if (StringUtil.isNotEmpty(paymentIdStr) && !paymentIdStr.contains(ChartConstant.LEFT_PARENTHESES)) {
            if (StringUtil.isNotEmpty(paymentIdStr)) {
                //处理关联应收款的编号（text_13）（是数组）
                Long paymentId = StringUtil.StringToLong(paymentIdStr, -1L);
                String paymentSerialNo = paymentIdSerialNoMap.get(paymentId);
                planData = paymentIdDataMap.get(paymentId);
                //回款单、应收款都为红冲
                Integer isRed = data.getInteger(PaymentSheetEnum.IS_RED.getAttr());
                if (planData != null && Objects.equals(isRed, BasicConstant.ONE)) {
                    Integer planIsRed = planData.getInteger(PaymentEnum.IS_RED.getAttr());
                    Integer planRefType = planData.getInteger(PaymentEnum.REF_TYPE.getAttr());
                    //应收款为红冲，且不是关联的退货退款（refType是退货退款时，应收款的originId是-1，且关联的是退货退款id）
                    boolean normalPlanFlag = Objects.equals(planIsRed, BasicConstant.ONE) && !Objects.equals(planRefType, XbbRefTypeEnum.REFUND.getCode());
                    if (normalPlanFlag) {
                        //红冲的回款单，关联的应收款也是红冲，则需要拿到红冲应收款关联的原始应收款
                        paymentIdStr = planData.getString(PaymentEnum.ORIGIN_ID.getAttr());
                        //关联原始应收款的id不为空，且不为-1
                        boolean flag = StringUtil.isNotEmpty(paymentIdStr) && !Objects.equals(paymentIdStr, "-1") && !Objects.equals(StringUtil.StringToLong(paymentIdStr), -1L);
                        if (flag) {
                            //重置为原应收款
                            paymentId = StringUtil.StringToLong(paymentIdStr, -1L);
                            planData = paymentIdDataMap.get(paymentId);
                            if (planData == null) {
                                planData = new JSONObject();
                            }
                            paymentSerialNo = planData.getString("planSerialNo");
                            paymentSerialNo = paymentSerialNo == null? "": paymentSerialNo;
                        }
                    }
                }
                JSONArray paymentIdArray = new JSONArray();
                paymentIdArray.add(paymentId);
                data.put(PaymentSheetEnum.PAYMENT.getAttr(), paymentIdArray);
                if (paymentSerialNo != null) {
                    JSONArray paymentSerialNoArray = new JSONArray();
                    paymentSerialNoArray.add(paymentSerialNo);
                    data.put(PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr(), paymentSerialNoArray);
                }
            }
        }else if (StringUtil.isNotEmpty(paymentIdStr) && paymentIdStr.contains(ChartConstant.LEFT_PARENTHESES)) {
            JSONArray jsonArray = JSONArray.parseArray(paymentIdStr);
            Set<Long> idSet = new HashSet();
            if (Objects.nonNull(jsonArray)) {
                for (Object object : jsonArray) {
                    if (object != null) {
                        Long id = StringUtil.StringToLong(object.toString());
                        idSet.add(id);
                    }
                }
                data.put(PaymentSheetEnum.PAYMENT.getAttr(), idSet);
                JSONArray linkTextArray = JSONArray.parseArray(data.getString(PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr()));
                if (Objects.nonNull(linkTextArray)) {
                    JSONArray newTextArray = new JSONArray();
                    for (Object object : linkTextArray) {
                        if (object != null) {
                            newTextArray.add(object);
                        }
                    }
                    data.put(PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr(), newTextArray);
                }
            }
        }
        //根据应收款，处理关联客户、关联合同
        if (planData != null) {
            String customerIdStr = planData.getString(PaymentEnum.CUSTOMER.getAttr());
            Long customerId = null;
            if (StringUtil.isNotEmpty(customerIdStr)) {
                customerId = StringUtil.StringToLong(customerIdStr);
            }
            String customerName = planData.getString(PaymentEnum.CUSTOMER_LINK_TEXT.getAttr());
            data.put(PaymentSheetEnum.CUSTOMER_ID.getAttr(), customerId);
            data.put(PaymentSheetEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), customerName);
            //处理关联合同及合同编号（text_4，text_12）（是数组）
            String contractIdStr = planData.getString(PaymentEnum.CONTRACT.getAttr());
            Long contractId = null;
            if (StringUtil.isNotEmpty(contractIdStr)) {
                contractId = StringUtil.StringToLong(contractIdStr);
            }
            if (contractId != null) {
                String contractNo = planData.getString(PaymentEnum.CONTRACT_LINK_TEXT.getAttr());
                JSONArray contractIdArray = new JSONArray();
                JSONArray contractSerialNoArray = new JSONArray();
                //合同id
                contractIdArray.add(contractId);
                //合同编号
                contractSerialNoArray.add(contractNo);
                data.put(PaymentSheetEnum.CONTRACT.getAttr(), contractIdArray);
                data.put(PaymentSheetEnum.CONTRACT_LINK_TEXT.getAttr(), contractSerialNoArray);
            }
        }
        //处理核销金额（num_7）
        double paymentAmount = data.getDoubleValue(PaymentSheetEnum.AMOUNT.getAttr());
        data.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(), paymentAmount);
        //处理归属人（array_1）
        Object belongIdObject = data.get("text_2");
        String belongId;
        if (belongIdObject instanceof JSONObject) {
            JSONObject belongIdJSONObject = (JSONObject) belongIdObject;
            belongId = belongIdJSONObject.getString("id");
            data.put("text_2", belongId);
        } else {
            belongId = data.getString("text_2");
        }
        if (belongId != null) {
            JSONArray belongIdArray = new JSONArray();
            belongIdArray.add(belongId);
            data.put(PaymentSheetEnum.BELONG_ID.getAttr(), belongIdArray);
        }
    }

    /**
     * 更新采购退货解释的脚本（所有公司）
     *
     * @param paymentSheetExplainsDTO 入参（校验码）
     * @return java.lang.String
     * @throws Exception 异常
     * @author zhouwq
     * @date 2020/3/17 14:02
     */
    @RequestMapping(value = "/returnedPurchase/explains", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String returnedPurchaseExplains(@RequestBody @Valid PaymentSheetExplainsDTO paymentSheetExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            //获取未删除的公司数量
            Map<String, Object> companyParam = new HashMap<>(1);
            companyParam.put("del", BasicConstant.ZERO);
            Integer companyCount = companyModel.getEntitysCount(companyParam);
            //分步对公司批量处理
            Integer pageSize = 300;
            //获取解释需要更新的值
            List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(XbbRefTypeEnum.RETURNED_PURCHASE.getAlias(), null, null, 0);
            List<String> addReturnedPurchaseAttr = Arrays.asList(ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.INVOICES.getAttr(),
                    ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), ReturnedPurchaseEnum.REFUND_INFO.getAttr());
            List<FieldAttrEntity> result = fieldAttrEntities.stream().filter(e -> addReturnedPurchaseAttr.contains(e.getAttr())).collect(Collectors.toList());
            for (int i = 0; i < companyCount;) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(i, pageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                //获取采购退货的表单解释列表
                List<PaasFormExplainEntity> formExplainList = scriptHelper.findExplainByCorpidSet(XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), corpidSet);
                //更新解释
                formExplainList.forEach(item -> {
                    String oldExplain = item.getExplains();
                    List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(oldExplain, FieldAttrEntity.class);
                    oldFieldAttrEntities.addAll(result);
                    String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                    item.setExplains(fieldAttrStr);
                });
                if (formExplainList.size() > 0) {
                    paasFormExplainModel.updateBatchExplains(formExplainList);
                }
                i = i + pageSize > companyCount ? companyCount : i + pageSize;
                LOG.warn("处理进度" + i + "/" + companyCount);
            }
            LOG.warn("-----------time consume returnedPurchaseExplains:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------处理完毕-----------");
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 更新采购退货解释的脚本（所有公司）  可重复刷,效率略慢
     *
     * @param paymentSheetExplainsDTO 入参（校验码）
     * @return java.lang.String
     * @throws Exception 异常
     * @author zhouwq
     * @date 2020/3/17 14:02
     */
    @RequestMapping(value = "/returnedPurchase/explains/two", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String returnedPurchaseExplainsTwo(@RequestBody @Valid PaymentSheetExplainsDTO paymentSheetExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            //获取未删除的公司数量
            Map<String, Object> companyParam = new HashMap<>(1);
            companyParam.put("del", BasicConstant.ZERO);
            Integer companyCount = companyModel.getEntitysCount(companyParam);
            //分步对公司批量处理
            Integer pageSize = 10;
            //获取解释需要更新的值
            List<FieldAttrEntity> fieldAttrEntities = InitExplainsHelper.initFieldAttrEntity(XbbRefTypeEnum.RETURNED_PURCHASE.getAlias(), null, null, 0);
            List<String> addReturnedPurchaseAttr = Arrays.asList(ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), ReturnedPurchaseEnum.PAY_SHEETS_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.INVOICES.getAttr(),
                    ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), ReturnedPurchaseEnum.REFUND_INFO.getAttr());
            List<FieldAttrEntity> result = fieldAttrEntities.stream().filter(e -> addReturnedPurchaseAttr.contains(e.getAttr())).collect(Collectors.toList());
            for (int i = 0; i < companyCount;) {
                //分步获取公司id集合
                Set<String> corpidSet = getCorpidSetbyStep(i, pageSize);
                if (Objects.equals(corpidSet.size(), BasicConstant.ZERO)) {
                    break;
                }
                //获取采购退货的表单解释列表
                List<PaasFormExplainEntity> formExplainList = scriptHelper.findExplainByCorpidSet(XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), corpidSet);
                //更新解释
                formExplainList.forEach(item -> {
                    String oldExplain = item.getExplains();
                    List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(oldExplain, FieldAttrEntity.class);
                    List<FieldAttrEntity> newFieldAttrLists = result.stream().filter(e -> oldFieldAttrEntities.stream().noneMatch(fieldAttrEntity -> Objects.equals(fieldAttrEntity.getAttr(), e.getAttr()))).collect(Collectors.toList());
                    oldFieldAttrEntities.addAll(newFieldAttrLists);
                    String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                    item.setExplains(fieldAttrStr);
                });
                paasFormExplainModel.updateBatchExplains(formExplainList);
                i = i + pageSize > companyCount ? companyCount : i + pageSize;
                LOG.warn("处理进度" + i + "/" + companyCount);
            }
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/init/fund/account", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initFundAccount(@RequestBody @Valid FundAccountExplainsDTO fundAccountExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fundAccountExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            if (Objects.equals(fundAccountExplainsDTO.getGreaterOrLess(), 0)) {
                params.put("addTimeEnd", fundAccountExplainsDTO.getAddTime());
            }else if (Objects.equals(fundAccountExplainsDTO.getGreaterOrLess(), 1)) {
                params.put("addTimeStart", fundAccountExplainsDTO.getAddTime());
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "大于等于或小于标识错误");
            }
            params.put("columns", "corpid");
            //获取未删除的公司数量
            List<CompanyEntity> companyList = companyModel.findEntitys(params);
            List<String> corpIdList = new ArrayList<>();
            companyList.forEach(e -> corpIdList.add(e.getCorpid()));
            if (corpIdList.size() > 0) {
                fundAccountModel.initFundAccount(corpIdList);
            }
            LOG.warn("-----------time consume initFundAccount:" + (DateTimeUtil.getInt() - timeStart));
        } catch (Exception e) {
            LOG.error("paymentSheetExplainsError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/init/fund/log", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initFundFlowLog(@RequestBody @Valid FundAccountExplainsDTO fundAccountExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fundAccountExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("columns", "id,corpid");
            List<FundAccountEntity> fundAccountEntities = fundAccountModel.findEntitys(params);
            //公司ID与默认资金账户ID对应关系
            Map<String, Long> fundAccountIdToCorpMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fundAccountEntities.forEach(e -> fundAccountIdToCorpMap.put(e.getCorpid(), e.getId()));
            int idx = 0;
            for (Map.Entry<String, Long> entry : fundAccountIdToCorpMap.entrySet()) {
                String corpid = entry.getKey();
                Long accountId = entry.getValue();
                scriptHelper.handleFundLogAsync(corpid, fundAccountExplainsDTO, accountId);
                LOG.warn("公司ID：" + corpid + " end---------------（所有公司）总处理进度---------------" + ++idx +"/" +fundAccountIdToCorpMap.size());
            }
            LOG.warn("-----------time consume initFundFlowLog:" + (DateTimeUtil.getInt() - timeStart));
        } catch (Exception e) {
            LOG.error("initFundFlowLogError", e);
        }
        LOG.warn("-----------处理完毕-----------");
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/init/fund/account/amount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initFundAccountAmount(@RequestBody @Valid FundAccountExplainsDTO fundAccountExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fundAccountExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.warn("-----------开始处理资金账户余额-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<String> corpIdList = fundAccountExplainsDTO.getCorpidList();
            if (corpIdList != null && corpIdList.size() == 1) {
                params.put("corpid", corpIdList.get(0));
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            params.put(StringConstant.DEL, DelEnum.NORMAL);
            List<FundAccountEntity> fundAccountEntities = fundAccountModel.findEntitys(params);
            //公司ID与默认资金账户ID对应关系
            Map<Long, String> fundAccountIdToCorpMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, Double> fundAccountAmountToAccountId = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fundAccountEntities.forEach(e -> {
                fundAccountIdToCorpMap.put(e.getId(), e.getCorpid());
                e.setAmount(e.getInitialAmount());
                fundAccountAmountToAccountId.put(e.getId(), 0D);
            });
            Map<String, Object> sheetParams = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            sheetParams.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            sheetParams.put("addTimeEnd", DateUtil.getNow());
            sheetParams.put(BasicConstant.ALONE_IN, SheetAloneEnum.getNotChildCodeList());
            for (Map.Entry<Long, String> entry : fundAccountIdToCorpMap.entrySet()) {
                String corpid = entry.getValue();
                Long accountId = entry.getKey();
                sheetParams.put(StringConstant.CORPID, corpid);
                List<PaymentSheetEntityExt> paymentSheetEntityExts = paymentSheetModel.getPaymentSheetByCorpidScript(sheetParams);
                List<PayPlanSheetEntityExt> paySheetEntityExts = payPlanSheetModel.getPaySheetByCorpidScript(sheetParams);
                for (PaymentSheetEntityExt paymentSheetEntityExt : paymentSheetEntityExts) {
                    JSONObject paymentSheetEntityExtData = paymentSheetEntityExt.getData();
                    if (paymentSheetEntityExtData != null) {
                        String fundAccount = paymentSheetEntityExtData.getString(PaymentSheetEnum.FUND_ACCOUNT.getAttr());
                        Long fundAccountId = 0L;
                        try {
                            fundAccountId = Long.valueOf(fundAccount);
                        } catch (NumberFormatException e) {
                            //不处理
                        }
                        if (Objects.equals(fundAccountId, accountId)) {
                            double dataDouble = FastJsonHelper.getDoubleOrDefaultFromFormData(paymentSheetEntityExtData, PaymentSheetEnum.AMOUNT.getAttr(), 0D);
                            fundAccountAmountToAccountId.merge(accountId, dataDouble, Arith::add);
                        }
                    }
                }
                for (PayPlanSheetEntityExt paySheetEntityExt : paySheetEntityExts) {
                    JSONObject data = paySheetEntityExt.getData();
                    if (data != null) {
                        String fundAccount = data.getString(PaySheetEnum.FUND_ACCOUNT.getAttr());
                        Long fundAccountId = 0L;
                        try {
                            fundAccountId = Long.valueOf(fundAccount);
                        } catch (NumberFormatException e) {
                            //不处理
                        }
                        if (Objects.equals(fundAccountId, accountId)) {
                            double dataDouble = -FastJsonHelper.getDoubleOrDefaultFromFormData(data, PaymentSheetEnum.AMOUNT.getAttr(), 0D);
                            fundAccountAmountToAccountId.merge(accountId, dataDouble, Arith::add);
                        }
                    }
                }
            }
            FundAccountEntity fundAccountEntity = new FundAccountEntity();
            fundAccountEntities.forEach(fundAccount -> {
                fundAccountAmountToAccountId.forEach((accountId, amount) -> {
                    if (fundAccount.getId().equals(accountId)) {
                        BigDecimal aa = fundAccount.getInitialAmount().add(BigDecimal.valueOf(amount));
                        fundAccountEntity.setAmount(aa);
                        fundAccountEntity.setId(accountId);
                        try {
                            fundAccountModel.update(fundAccountEntity);
                        } catch (XbbException e) {
                            e.printStackTrace();
                        }
                    }
                });
            });
            LOG.warn("-----------time consume initFundAccountAmount:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------处理完毕：资金账户余额-----------");
        } catch (Exception e) {
            LOG.error("initFundAccountAmountError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/init/paymentSheet/account", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initPaymentSheetAccount(@RequestBody @Valid FundAccountExplainsDTO fundAccountExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fundAccountExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("columns", "id,corpid");
            List<String> corpIdList = fundAccountExplainsDTO.getCorpidList();
            if (corpIdList != null && corpIdList.size() == 1) {
                params.put("corpid", corpIdList.get(0));
            }
            List<FundAccountEntity> fundAccountEntities = fundAccountModel.findEntitys(params);
            //公司ID与默认资金账户ID对应关系
            Map<String, Long> fundAccountIdToCorpMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fundAccountEntities.forEach(e -> fundAccountIdToCorpMap.put(e.getCorpid(), e.getId()));
            for (Map.Entry<String, Long> entry : fundAccountIdToCorpMap.entrySet()) {
                String corpid = entry.getKey();
                Long accountId = entry.getValue();
                scriptHelper.handleFundAccountInPaymentAsync(corpid, fundAccountExplainsDTO, accountId);
            }
            LOG.warn("-----------time consume initPaymentSheetAccount:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------初始化回款单资金账户字段脚本执行完毕-----------");
        } catch (Exception e) {
            LOG.error("initPaymentSheetAmountError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/repair/purchaseInvoiceAmount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String repairPurchaseInvoiceAmount(@RequestBody @Valid PurchaseInvoiceRepairAmountDTO purchaseInvoiceRepairAmountDTO) throws Exception {
        try{
            if (!proBaseConfig.getXbbCode().equals(purchaseInvoiceRepairAmountDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            List<String> corpidList = purchaseInvoiceRepairAmountDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpidList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "请传入公司id");
            }
            if (corpidList.size() > BasicConstant.ONE) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "每次只能处理一家公司的数据");
            }
            LOG.info("共有" + corpidList.size() + "家数据");
            Integer i = 0;
            if (CollectionsUtil.isNotEmpty(corpidList)) {
                Integer modelType = purchaseInvoiceRepairAmountDTO.getModelType();
                for (String corpid : corpidList) {
                    i++;
                    LOG.info("现在是第" + i + "家公司");
                    purchaseInvoiceRepairAmountDTO.setCorpid(corpid);
                    //第一步查询所有的合同
                    fundFixDataService.repairPurchaseInvoiceAmount(purchaseInvoiceRepairAmountDTO);
                }
            }
        } catch (Exception e) {
            LOG.error("repairPurchaseInvoiceAmountError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    @RequestMapping(value = "/init/fundAccountAttr", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initFundAccountAttr(@RequestBody @Valid FundAccountExplainsDTO fundAccountExplainsDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fundAccountExplainsDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            List<String> corpIdList = fundAccountExplainsDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpIdList)) {
                corpIdList = companyModel.getCorpidList();
            }
            Map<String, Object> fundParams = new HashMap<>(1 << 4);
            fundParams.put("del", DelEnum.NORMAL.getDel());
            if (corpIdList == null) {
                return "";
            }
            LOG.info("共有" + corpIdList.size() + "家数据");
            int i = 0;
            for (String corpid : corpIdList) {
                i++;
                LOG.info("现在是第" + i + "家公司");
                fundParams.put("corpid", corpid);
                List<PaymentSheetEntityExt> paymentSheetEntityExts = paymentSheetModel.findEntitys(fundParams);
                if (paymentSheetEntityExts != null && paymentSheetEntityExts.size() > 0) {
                    List<PaymentSheetUpdateDTO> paymentSheetUpdateDTOList = new ArrayList<>();
                    for (PaymentSheetEntityExt entityExt : paymentSheetEntityExts) {
                        JSONObject oldData = entityExt.getData();
                        Object fundAccountIdObj = oldData.get(PaymentSheetEnum.FUND_ACCOUNT.getAttr());
                        if (fundAccountIdObj == null || fundAccountIdObj instanceof String) {
                            continue;
                        }
                        PaymentSheetUpdateDTO paymentSheetUpdateDTO = new PaymentSheetUpdateDTO();
                        paymentSheetUpdateDTO.setId(entityExt.getId());
                        JSONObject data = new JSONObject();
                        data.put(PaymentSheetEnum.FUND_ACCOUNT.getAttr(), fundAccountIdObj.toString());
                        paymentSheetUpdateDTO.setData(data);
                        paymentSheetUpdateDTOList.add(paymentSheetUpdateDTO);
                    }
                    PaymentSheetUpdateBatchDTO paymentSheetUpdateBatchDTO = new PaymentSheetUpdateBatchDTO();
                    paymentSheetUpdateBatchDTO.setCorpid(corpid);
                    paymentSheetUpdateBatchDTO.setPaymentSheetUpdateList(paymentSheetUpdateDTOList);
                    paymentSheetService.updateAttrBatch(paymentSheetUpdateBatchDTO, false);
                }
                List<PayPlanSheetEntityExt> payPlanSheetEntityExts = payPlanSheetModel.findEntitys(fundParams);
                if (payPlanSheetEntityExts != null && payPlanSheetEntityExts.size() > 0) {
                    List<PaySheetUpdateDTO> paySheetUpdateDTOList = new ArrayList<>();
                    for (PayPlanSheetEntityExt entityExt : payPlanSheetEntityExts) {
                        JSONObject oldData = entityExt.getData();
                        Object fundAccountIdObj = oldData.get(PaySheetEnum.FUND_ACCOUNT.getAttr());
                        if (fundAccountIdObj == null || fundAccountIdObj instanceof String) {
                            continue;
                        }
                        PaySheetUpdateDTO paySheetUpdateDTO = new PaySheetUpdateDTO();
                        paySheetUpdateDTO.setId(entityExt.getId());
                        JSONObject data = new JSONObject();
                        data.put(PaySheetEnum.FUND_ACCOUNT.getAttr(), fundAccountIdObj.toString());
                        paySheetUpdateDTO.setData(data);
                        paySheetUpdateDTOList.add(paySheetUpdateDTO);
                    }
                    PaySheetUpdateBatchDTO paySheetUpdateBatchDTO = new PaySheetUpdateBatchDTO();
                    paySheetUpdateBatchDTO.setCorpid(corpid);
                    paySheetUpdateBatchDTO.setPaySheetUpdateList(paySheetUpdateDTOList);
                    payPlanSheetService.updateAttrBatch(paySheetUpdateBatchDTO, false);
                }
            }
            LOG.warn("-----------time consume fundAccountAttr:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------初始化回款单资金账户字段脚本执行完毕-----------");
        } catch (Exception e) {
            LOG.error("initPaymentSheetAmountError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 客户对账单：将data里面表示对账单据id的text_1和对账单据业务类型的num_1的数据
     *           同步到新增字段sys_long_2和sys_long_1
     * @param initCustomerStatementDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/transform/statementBusinessTypeAndStatementId", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String transformStatementBusinessTypeAndStatementId(@RequestBody @Valid InitCustomerStatementDTO initCustomerStatementDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(initCustomerStatementDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.warn("-----------更新客户对账单字段开始执行-----------");
            long timeStart = DateTimeUtil.getInt();
            List<String> corpIdList = initCustomerStatementDTO.getCorpidList();
            Long timestamp = initCustomerStatementDTO.getTimestamp();
            Integer initFlag = initCustomerStatementDTO.getInitFlag();
            if (CollectionsUtil.isEmpty(corpIdList)) {
                corpIdList = companyModel.getCorpidList();
            }
            if (Objects.isNull(corpIdList)) {
                return "";
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            param.put("del",DelEnum.NORMAL.getDel());
            if (Objects.equals(initFlag,BasicConstant.ONE)){
                param.put("addTimeEnd",timestamp);
            }else if (Objects.equals(initFlag,BasicConstant.TWO)){
                //代表增量处理数据
                param.put("addTimeStart",timestamp);
            }
            LOG.info("共有" + corpIdList.size() + "家数据");
            int i = 0;
            for (String corpid : corpIdList) {
                i++;
                param.put("corpid",corpid);
                LOG.info("现在是第" + i + "家公司" + "/共" + corpIdList.size() + "家公司");
                Long idGte = 0L;
                while (true){
                    param.put("idGte",idGte);
                    List<CustomerStatementEntity> customerStatementEntities = customerStatementModel.findEntitys(param);
                    if (CollectionsUtil.isEmpty(customerStatementEntities)){
                        break;
                    }
                    idGte = customerStatementEntities.get(customerStatementEntities.size() - 1).getId();
                    List<CustomerStatementEntity> updateCustomerStatements = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    customerStatementEntities.forEach(entity -> {
                        CustomerStatementEntity customerStatementEntity = new CustomerStatementEntity();
                        JSONObject originData = entity.getData();
                        boolean isNull = Objects.isNull(customerStatementEntity.getSysLong2()) || Objects.isNull(customerStatementEntity.getSysLong1());
                        if (Objects.nonNull(originData) && isNull){
                            //获取原来你对账单据的业务类型和对账单据的id
                            Integer businessType = originData.getInteger(CustomerStatementEnum.BUSINESS_TYPE.getAttr());
                            Long statementId = originData.getLong(CustomerStatementEnum.STATEMENT_ID.getAttr());
                            customerStatementEntity.setSysLong1(businessType);
                            customerStatementEntity.setSysLong2(statementId);
                            customerStatementEntity.setUpdateTime(DateUtil.getNow());
                            customerStatementEntity.setId(entity.getId());
                            customerStatementEntity.setCorpid(entity.getCorpid());
                            updateCustomerStatements.add(customerStatementEntity);
                        }
                    });
                    //根据公司id进行批量更新
                    if (CollectionsUtil.isNotEmpty(updateCustomerStatements)){
                        customerStatementModel.updateBatchAbnormalForDB(updateCustomerStatements,corpid,false);
                    }
                }
            }
            LOG.warn("-----------time consume statementBusinessTypeAndStatementId:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------更新客户对账单字段执行完毕-----------");
        } catch (Exception e) {
            LOG.error("initPaymentSheetAmountError", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 修复资金账户流水中的重复的数据
     *
     * @param paymentSheetDataDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/fundAccountFlow/fixRepeatData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRepeatData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            List<String> corpIdList = paymentSheetDataDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpIdList) || Objects.isNull(paymentSheetDataDTO.getType())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            Map<String, Object> fundParams = new HashMap<>(1 << 4);
            fundParams.put("del", DelEnum.NORMAL.getDel());
            fundParams.put("type", paymentSheetDataDTO.getType());
            LOG.info("共有" + corpIdList.size() + "家数据");
            int i = 0;
            for (String corpid : corpIdList) {
                i++;
                LOG.info("现在是第" + i + "家公司");
                fundParams.put("corpid", corpid);
                List<FundAccountFlowEntity> fundAccountFlowEntities = fundAccountFlowModel.findRepeatSheetList(fundParams);
                if (CollectionsUtil.isEmpty(fundAccountFlowEntities)) {
                    continue;
                }
                //上面已经得到了重复的单据id，这时候根据单据id再去做查询出所有的数据
                List<Long> sheetIdList = fundAccountFlowEntities.stream().map(e->e.getSheetId()).collect(Collectors.toList());
                List<Long> fundAccountFlowIdList = fundAccountFlowEntities.stream().map(e->e.getId()).collect(Collectors.toList());
                fundParams.remove("sheetIdIn");
                fundParams.put("sheetIdIn", sheetIdList);
                List<FundAccountFlowEntity> shouldHandleFundAccountList = fundAccountFlowModel.findEntitys(fundParams);
                Iterator<FundAccountFlowEntity>  iterator = shouldHandleFundAccountList.iterator();
                while (iterator.hasNext()) {
                    FundAccountFlowEntity newFundAccountFlowEntity = iterator.next();
                    if (fundAccountFlowIdList.contains(newFundAccountFlowEntity.getId())) {
                        iterator.remove();
                    }
                }
                //获取账户id列表
                Set<Long> accountSet = fundAccountFlowEntities.stream().map(e -> e.getAccountId()).collect(Collectors.toSet());
                Map<String, Object> fundAccountMap = new HashMap<>();
                fundAccountMap.put("corpid", corpid);
                fundAccountMap.put("idIn", accountSet);
                List<FundAccountEntity> fundAccountEntities = fundAccountModel.findEntitys(fundAccountMap);
                for (FundAccountEntity fundAccountEntity : fundAccountEntities) {
                    double amount = 0d;
                    for (FundAccountFlowEntity fundAccountFlowEntity : shouldHandleFundAccountList) {
                        if (Objects.equals(fundAccountEntity.getId(), fundAccountFlowEntity.getAccountId())) {
                            amount = Arith.sub(amount, fundAccountFlowEntity.getSheetAmount());
                        }
                    }
                    fundAccountEntity.setAmount(new BigDecimal(amount));
                }
                fundAccountModel.updateBatchAmount(fundAccountEntities);
                //再更新流水表中的删除标识为已删除
                shouldHandleFundAccountList.forEach(fundAccountFlowEntity ->  {
                    fundAccountFlowEntity.setDel(BasicConstant.ONE);
                });
                fundAccountFlowModel.updateBatch(shouldHandleFundAccountList, corpid);
            }
            LOG.warn("-----------time consume fixRepeatData:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------修复其它支出单、其它收入单在流水表中多插入-----------");
        } catch (Exception e) {
            LOG.error("fixRepeatData", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 客户对账单默认打印模板->往来明细中 添加回款类型子段,corpidList = [],代表全公司刷
     *
     * @param paymentSheetDataDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/customerStatement/initCustomerStatementPrintTemplate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String initCustomerStatementPrintTemplate(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            List<String> corpIdList = paymentSheetDataDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpIdList)) {
                corpIdList = companyModel.getCorpidList();
                //默认打印模板公司id
                corpIdList.add("0");
            }
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("del", DelEnum.NORMAL.getDel());
            params.put("businessType",XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
            LOG.info("共有" + corpIdList.size() + "家数据");
            int i = 0;

            JSONObject paymentType = new JSONObject();
            paymentType.put("attr", CustomerStatementEnum.PAYMENT_TYPE.getAttr());
            paymentType.put("attrName", CustomerStatementEnum.PAYMENT_TYPE.getAttrName());
            paymentType.put("saasAttr", CustomerStatementEnum.PAYMENT_TYPE.getSaasAttr());
            paymentType.put("isShow", true);

            for (String corpid : corpIdList) {
                i++;
                LOG.info("现在是第" + i + "家公司");
                params.put("corpid", corpid);
                List<PaasPrintTemplateEntity> updateBatchList = new ArrayList<>();
                List<PaasPrintTemplateEntity> paasPrintTemplateEntities = paasPrintTemplateModel.list(params);
                if (CollectionsUtil.isEmpty(paasPrintTemplateEntities)) {
                    continue;
                }
                Iterator<PaasPrintTemplateEntity> iterator = paasPrintTemplateEntities.iterator();
                while (iterator.hasNext()){
                    PaasPrintTemplateEntity entity = iterator.next();
                    String html = entity.getHtml();
                    JSONArray jsonArray = FastJsonHelper.parseArray(html);
                    JSONArray newJsonArray = new JSONArray();
                    if (CollectionsUtil.isNotEmpty(jsonArray)){
                        for (int j = 0; j < jsonArray.size(); j++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(j);
                            if(PrintSpecialAttrEnum.CUSTOMER_STATEMENT_DETAIL.getAttrName().equals(jsonObject.getString("name"))){
                                JSONObject options = FastJsonHelper.getJsonObjectOrDefaultFromFormData(jsonObject, "options", new JSONObject());
                                JSONArray dispalyAttrList = FastJsonHelper.getJsonArrOrDefaultFromFormData(options, "dispalyAttrList", new JSONArray());
                                dispalyAttrList.add(paymentType);
                                options.put("dispalyAttrList",dispalyAttrList);
                                jsonObject.put("options",options);
                            }
                            newJsonArray.add(jsonObject);
                        }
                        entity.setHtml(newJsonArray.toJSONString());
                        updateBatchList.add(entity);
                    }
                }
                if (CollectionsUtil.isNotEmpty(updateBatchList)){
                    paasPrintTemplateModel.updateBatch(updateBatchList,corpid);
                }
            }
            LOG.info("-----------time consume initCustomerStatementPrintTemplate:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------客户对账单打印模板初始化成功-----------");
        } catch (Exception e) {
            LOG.error("initCustomerStatementPrintTemplate", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 回滚客户对账单默认打印模板添加的 ->往来明细中 回款类型字段
     * @param paymentSheetDataDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/customerStatement/rollbackCustomerStatementPrintTemplate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String rollbackCustomerStatementPrintTemplate(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            long timeStart = DateTimeUtil.getInt();
            List<String> corpIdList = paymentSheetDataDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpIdList)) {
                corpIdList = companyModel.getCorpidList();
                //默认打印模板公司id
                corpIdList.add("0");
            }
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("del", DelEnum.NORMAL.getDel());
            params.put("businessType",XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
            LOG.info("共有" + corpIdList.size() + "家数据");
            int i = 0;

            JSONObject paymentType = new JSONObject();
            paymentType.put("attr", CustomerStatementEnum.PAYMENT_TYPE.getAttr());
            paymentType.put("attrName", CustomerStatementEnum.PAYMENT_TYPE.getAttrName());
            paymentType.put("saasAttr", CustomerStatementEnum.PAYMENT_TYPE.getSaasAttr());
            paymentType.put("isShow", true);

            for (String corpid : corpIdList) {
                i++;
                LOG.info("现在是第" + i + "家公司");
                params.put("corpid", corpid);
                List<PaasPrintTemplateEntity> updateBatchList = new ArrayList<>();
                List<PaasPrintTemplateEntity> paasPrintTemplateEntities = paasPrintTemplateModel.list(params);
                if (CollectionsUtil.isEmpty(paasPrintTemplateEntities)) {
                    continue;
                }
                Iterator<PaasPrintTemplateEntity> iterator = paasPrintTemplateEntities.iterator();
                while (iterator.hasNext()){
                    PaasPrintTemplateEntity entity = iterator.next();
                    String html = entity.getHtml();
                    JSONArray jsonArray = FastJsonHelper.parseArray(html);
                    JSONArray newJsonArray = new JSONArray();
                    if (CollectionsUtil.isNotEmpty(jsonArray)){
                        for (int j = 0; j < jsonArray.size(); j++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(j);
                            if(PrintSpecialAttrEnum.CUSTOMER_STATEMENT_DETAIL.getAttrName().equals(jsonObject.getString("name"))){
                                JSONObject options = FastJsonHelper.getJsonObjectOrDefaultFromFormData(jsonObject, "options", new JSONObject());
                                JSONArray dispalyAttrList = FastJsonHelper.getJsonArrOrDefaultFromFormData(options, "dispalyAttrList", new JSONArray());
                                dispalyAttrList.removeIf(item -> {
                                    JSONObject json = (JSONObject)item;
                                    return Objects.equals(json.get("attr"),CustomerStatementEnum.PAYMENT_TYPE.getAttr());
                                });
                                options.put("dispalyAttrList",dispalyAttrList);
                                jsonObject.put("options",options);
                            }
                            newJsonArray.add(jsonObject);
                        }
                        entity.setHtml(newJsonArray.toJSONString());
                        updateBatchList.add(entity);
                    }
                }
                if (CollectionsUtil.isNotEmpty(updateBatchList)){
                    paasPrintTemplateModel.updateBatch(updateBatchList,corpid);
                }
            }
            LOG.info("-----------time consume initCustomerStatementPrintTemplate:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------客户对账单打印模板初始化成功-----------");
        } catch (Exception e) {
            LOG.error("initCustomerStatementPrintTemplate", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 修复预收款用户团队脏数据,主要是同步预收款的团队数据需要跟客户的数据一致
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixPaymentBalanceUserData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPaymentBalanceUserData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paymentBalanceUserModel.getAllCorpList();
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Map<String, Object> param = new HashMap<>();
        param.put("del", BasicConstant.ZERO);
        List<Long> customerIdList = new ArrayList<>();
        Map<String, Object> cusomerUserParam = new HashMap<>();
        int i = 0;
        for (String corpid : corpidList) {
            try {
                i++;
                LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
                param.put("corpid", corpid);
                List<PaymentBalanceUserEntity> paymentBalanceUserEntityList = paymentBalanceUserModel.findEntitys(param);
                if (CollectionsUtil.isEmpty(paymentBalanceUserEntityList)) {
                    continue;
                }
                //然后去查询这家公司客户团队表中的信息
                Map<Long, List<PaymentBalanceUserEntity>> paymentBalanceUserMap = paymentBalanceUserEntityList.stream().collect(Collectors.groupingBy(PaymentBalanceUserEntity::getCustomerId));
                customerIdList = paymentBalanceUserEntityList.stream().map(PaymentBalanceUserEntity::getCustomerId).distinct().collect(Collectors.toList());
                //一个dataId只会对应一个cutomerId
                Map<Long, Long> customer2dataIdMap = new HashMap<>();
                paymentBalanceUserEntityList.forEach(paymentBalanceUserEntity -> {
                    customer2dataIdMap.put(paymentBalanceUserEntity.getCustomerId(), paymentBalanceUserEntity.getDataId());
                });

                cusomerUserParam.put("corpid", corpid);
                cusomerUserParam.put("dataIdIn", customerIdList);
                List<CustomerUserEntity> customerUserEntityList = customerUserModel.findEntitys(cusomerUserParam);
                if (CollectionsUtil.isEmpty(customerUserEntityList)) {
                    continue;
                }
                Map<Long, List<CustomerUserEntity>> customerUserEntityMap = customerUserEntityList.stream().collect(Collectors.groupingBy(CustomerUserEntity::getDataId));
                //需要根据客户团队整理出哪些需要删除的，哪些需要新增的
                List<PaymentBalanceUserEntity> shouldAddList = new ArrayList<>();
                List<PaymentBalanceUserEntity> shouldDeleteList = new ArrayList<>();
                for (Map.Entry<Long, List<CustomerUserEntity>> entry: customerUserEntityMap.entrySet()) {
                    Long key = entry.getKey();
                    List<CustomerUserEntity> customerUserEntityListSen = entry.getValue();
                    //然后根据user_id和del分个组
                    Map<String, List<CustomerUserEntity>> userId2delMap = customerUserEntityListSen.stream().collect(Collectors.groupingBy(CustomerUserEntity::getUserId));
                    Map<String, List<Integer>> newUserId2delMap = new HashMap<>();
                    for (Map.Entry<String, List<CustomerUserEntity>> entrySen : userId2delMap.entrySet()) {
                        List<CustomerUserEntity> tempList = entrySen.getValue();
                        List<Integer> tempDelList = new ArrayList<>();
                        tempList.forEach(customerUserEntity -> {
                            tempDelList.add(customerUserEntity.getDel());
                        });
                        newUserId2delMap.put(entrySen.getKey(), tempDelList);
                    }

                    List<PaymentBalanceUserEntity> paymentBalanceUserEntities = paymentBalanceUserMap.get(key);
                    Map<String, PaymentBalanceUserEntity> user2EntityMap = paymentBalanceUserEntities.stream().collect(Collectors.toMap(PaymentBalanceUserEntity::getUserId, paymentBalanceUserEntity -> paymentBalanceUserEntity));
                    List<String> hasDeleteIdList = new ArrayList<>();
                    for (CustomerUserEntity customerUserEntity : customerUserEntityListSen) {
                        Long customerUserDataId = customerUserEntity.getDataId();
                        if (!user2EntityMap.containsKey(customerUserEntity.getUserId()) && Objects.equals(BasicConstant.ZERO, customerUserEntity.getDel())) {
                            PaymentBalanceUserEntity  paymentBalanceUserEntity = new PaymentBalanceUserEntity();
                            BeanUtil.copyProperties(customerUserEntity,paymentBalanceUserEntity);
                            paymentBalanceUserEntity.setCustomerId(customerUserEntity.getDataId());
                            paymentBalanceUserEntity.setDataId(customer2dataIdMap.get(customerUserDataId));
                            paymentBalanceUserEntity.setAddTime(DateTimeUtil.getInt());
                            paymentBalanceUserEntity.setUpdateTime(DateTimeUtil.getInt());
                            shouldAddList.add(paymentBalanceUserEntity);
                        }else if (user2EntityMap.containsKey(customerUserEntity.getUserId()) && Objects.equals(BasicConstant.ONE, customerUserEntity.getDel())) {
                            List<Integer> delTagList = newUserId2delMap.get(customerUserEntity.getUserId());
                            //主要一个用户可能在团队里面增增减减
                            if (!delTagList.contains(BasicConstant.ZERO)) {
                                if (!hasDeleteIdList.contains(customerUserEntity.getUserId())) {
                                    hasDeleteIdList.add(customerUserEntity.getUserId());
                                    shouldDeleteList.add(user2EntityMap.get(customerUserEntity.getUserId()));
                                }
                            }
                        }
                    }
                }
                  if (CollectionsUtil.isNotEmpty(shouldAddList)) {
                    paymentBalanceUserModel.insertBatch(shouldAddList);
                  }
                  if (CollectionsUtil.isNotEmpty(shouldDeleteList)) {
                    paymentBalanceUserModel.deleteBatchUser(shouldDeleteList, corpid);
                 }
            }catch (Exception e) {
                LOG.error("fixPayBalanceUserData error : {}, {}", corpid, e);
            }
        }
        LOG.info("-----------time consume fixPayBalanceUserData:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     * 修复预付款用户团队脏数据,主要是同步预收款的团队数据需要跟客户的数据一致
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixPayBalanceUserData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPayBalanceUserData(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = payBalanceUserModel.getAllCorpList();
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Map<String, Object> param = new HashMap<>();
        param.put("del", BasicConstant.ZERO);
        List<Long> supplierIdList = new ArrayList<>();
        Map<String, Object> supplierUserParam = new HashMap<>();
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
            param.put("corpid", corpid);
            List<PayBalanceUserEntity> payBalanceUserEntityList = payBalanceUserModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(payBalanceUserEntityList)) {
                continue;
            }
            //然后去查询这家公司客户团队表中的信息
            Map<Long, List<PayBalanceUserEntity>> paymentBalanceUserMap = payBalanceUserEntityList.stream().collect(Collectors.groupingBy(PayBalanceUserEntity::getSupplierId));
            supplierIdList = payBalanceUserEntityList.stream().map(PayBalanceUserEntity::getSupplierId).distinct().collect(Collectors.toList());
            //一个dataId只会对应一个cutomerId
            Map<Long, Long> supplier2dataIdMap = new HashMap<>();
            payBalanceUserEntityList.forEach(payBalanceUserEntity -> {
                supplier2dataIdMap.put(payBalanceUserEntity.getSupplierId(), payBalanceUserEntity.getDataId());
            });

            supplierUserParam.put("corpid", corpid);
            supplierUserParam.put("dataIdIn", supplierIdList);
            List<SupplierUserEntity> supplierUserEntities = supplierUserModel.findEntitys(supplierUserParam);
            if (CollectionsUtil.isEmpty(supplierUserEntities)) {
                continue;
            }
            Map<Long, List<SupplierUserEntity>> supplierUserEntityMap = supplierUserEntities.stream().collect(Collectors.groupingBy(SupplierUserEntity::getDataId));
            //需要根据客户团队整理出哪些需要删除的，哪些需要新增的
            List<PayBalanceUserEntity> shouldAddList = new ArrayList<>();
            List<PayBalanceUserEntity> shouldDeleteList = new ArrayList<>();
            for (Map.Entry<Long, List<SupplierUserEntity>> entry: supplierUserEntityMap.entrySet()) {
                Long key = entry.getKey();
                List<SupplierUserEntity> supplierUserEntityListSen = entry.getValue();
                //然后根据user_id和del分个组
                Map<String, List<SupplierUserEntity>> userId2delMap = supplierUserEntityListSen.stream().collect(Collectors.groupingBy(SupplierUserEntity::getUserId));
                Map<String, List<Integer>> newUserId2delMap = new HashMap<>();
                for (Map.Entry<String, List<SupplierUserEntity>> entrySen : userId2delMap.entrySet()) {
                    List<SupplierUserEntity> tempList = entrySen.getValue();
                    List<Integer> tempDelList = new ArrayList<>();
                    tempList.forEach(customerUserEntity -> {
                        tempDelList.add(customerUserEntity.getDel());
                    });
                    newUserId2delMap.put(entrySen.getKey(), tempDelList);
                }

                List<PayBalanceUserEntity> payBalanceUserEntities = paymentBalanceUserMap.get(key);
                Map<String, PayBalanceUserEntity> user2EntityMap = payBalanceUserEntities.stream().collect(Collectors.toMap(PayBalanceUserEntity::getUserId, paymentBalanceUserEntity -> paymentBalanceUserEntity));
                List<String> hasDeleteIdList = new ArrayList<>();
                for (SupplierUserEntity supplierUserEntity : supplierUserEntityListSen) {
                    Long supplierUserDataId = supplierUserEntity.getDataId();
                    if (!user2EntityMap.containsKey(supplierUserEntity.getUserId()) && Objects.equals(BasicConstant.ZERO, supplierUserEntity.getDel())) {
                        PayBalanceUserEntity  payBalanceUserEntity = new PayBalanceUserEntity();
                        BeanUtil.copyProperties(supplierUserEntity,payBalanceUserEntity);
                        payBalanceUserEntity.setSupplierId(supplierUserEntity.getDataId());
                        payBalanceUserEntity.setDataId(supplier2dataIdMap.get(supplierUserDataId));
                        payBalanceUserEntity.setAddTime(DateTimeUtil.getInt());
                        payBalanceUserEntity.setUpdateTime(DateTimeUtil.getInt());
                        shouldAddList.add(payBalanceUserEntity);
                    }else if (user2EntityMap.containsKey(supplierUserEntity.getUserId()) && Objects.equals(BasicConstant.ONE, supplierUserEntity.getDel())) {
                        List<Integer> delTagList = newUserId2delMap.get(supplierUserEntity.getUserId());
                        //主要一个用户可能在团队里面增增减减
                        if (!delTagList.contains(BasicConstant.ZERO)) {
                            if (!hasDeleteIdList.contains(supplierUserEntity.getUserId())) {
                                hasDeleteIdList.add(supplierUserEntity.getUserId());
                                shouldDeleteList.add(user2EntityMap.get(supplierUserEntity.getUserId()));
                            }
                        }
                    }
                }
            }
            if (CollectionsUtil.isNotEmpty(shouldAddList)) {
                payBalanceUserModel.insertBatch(shouldAddList);
            }
            if (CollectionsUtil.isNotEmpty(shouldDeleteList)) {
                payBalanceUserModel.deleteBatchUser(shouldDeleteList, corpid);
            }
        }
        LOG.info("-----------time consume fixPayBalanceUserData:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     * 修复红冲回款回款金额、核销金额为正错误问题
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixRedPaymentSheetAmount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRedPaymentSheetAmount(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            //获取开了工作流的公司
            corpidList = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.WORKFLOW.getAlias());
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Map<String, Object> param = new HashMap<>();
        param.put("del", BasicConstant.ZERO);
        param.put("updateTimeStart",paymentSheetDataDTO.getUpdateTimeStart());
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
            param.put("corpid", corpid);
            List<PaymentSheetEntityExt> paymentSheetEntityList = paymentSheetModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(paymentSheetEntityList)) {
                continue;
            }
            List<UpdateDataEntity> updateList = new ArrayList<>();
            for (PaymentSheetEntityExt paymentSheetEntity : paymentSheetEntityList){
                double amount;
                double writeOffAmount;
                boolean isUpdateAmount = false;
                boolean isUpdateWriteAmount = false;
                JSONObject jsonObject = new JSONObject();
                JSONObject data = paymentSheetEntity.getData();
                String sheetType = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                boolean isRed = PaymentSheetTypeEnum.isRed(sheetType);
                PaymentSheetTypeEnum paymentSheetTypeEnum = PaymentSheetTypeEnum.getByCode(sheetType);
                if (isRed){
                    amount = data.getDoubleValue(PaymentSheetEnum.AMOUNT.getAttr());
                    writeOffAmount = data.getDoubleValue(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr());
                    switch (paymentSheetTypeEnum){
                        case RED_WRITE_OFF:
                        case RED_WRITE_OFF_PREPAYMENT:
                            //是否红冲预收款核销 或者红冲已核销类型，此时更新核销金额和回款金额两个字段
                            //如果回款金额和核销金额大于0 取反
                            if (amount > 0){
                                amount = -amount;
                                isUpdateAmount = true;
                            }
                            if (writeOffAmount > 0){
                                writeOffAmount = -writeOffAmount;
                                isUpdateWriteAmount = true;
                            }
                            if (isUpdateAmount){
                                jsonObject.put(PaymentSheetEnum.AMOUNT.getAttr(),amount);
                            }
                            if (isUpdateWriteAmount){
                                jsonObject.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),writeOffAmount);
                            }
                            break;
                        case RED_PREPAYMENT:
                            //是否红冲预收款余额类型，此时更新回款金额
                            //如果回款金额大于0 取反
                            if (amount > 0){
                                amount = -amount;
                                isUpdateAmount = true;
                            }
                            if (isUpdateAmount){
                                jsonObject.put(PaymentSheetEnum.AMOUNT.getAttr(),amount);
                            }
                            break;
                        case RED_WRITE_OFF_BALANCE:
                            //是否红冲预收款核销（退到余额）类型，此时更新核销金额
                            //核销金额大于0 取反
                            if (writeOffAmount > 0){
                                writeOffAmount = -writeOffAmount;
                                isUpdateWriteAmount = true;
                            }
                            if (isUpdateWriteAmount){
                                jsonObject.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),writeOffAmount);
                            }
                            break;
                        default:
                            break;
                    }
                    if(jsonObject.size() > 0){
                        UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(paymentSheetEntity.getId(), jsonObject, corpid);
                        updateList.add(updateDataEntity);
                    }
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)){
                paymentSheetModel.updateBatch(updateList,corpid);
            }
        }
        LOG.info("-----------time consume fixRedPaymentSheetAmount:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }
    /**
     * 修复红冲其他收入单回款金额、核销金额为正错误问题
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixRedOtherIncomeAmount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRedOtherIncomeAmount(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            //获取开了工作流的公司
            corpidList = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.WORKFLOW.getAlias());
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Map<String, Object> param = new HashMap<>();
        param.put("del", BasicConstant.ZERO);
        param.put("updateTimeStart",paymentSheetDataDTO.getUpdateTimeStart());
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
            param.put("corpid", corpid);
            List<OtherIncomeEntity> entitys = otherIncomeModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(entitys)) {
                continue;
            }
            List<UpdateDataEntity> updateList = new ArrayList<>();
            for (OtherIncomeEntity entity : entitys){
                JSONObject jsonObject = new JSONObject();
                JSONObject data = entity.getData();
                String isRed = data.getString(OtherIncomeEnum.SHEET_TYPE_OTHER.getAttr());
                //是否红冲
                boolean red = OtherIncomeSheetTypeEnum.isRed(isRed);
                if (red){
                    double amount = data.getDoubleValue(OtherIncomeEnum.AMOUNT.getAttr());
                    if (amount < 0){
                        continue;
                    }else {
                        amount = -amount;
                    }
                    jsonObject.put(OtherIncomeEnum.AMOUNT.getAttr(),amount);
                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                    updateList.add(updateDataEntity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)){
                otherIncomeModel.updateBatch(updateList,corpid);
            }
        }
        LOG.info("-----------time consume fixRedOtherIncomeAmount:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }
    /**
     * 修复红冲其他支出单单回款金额、核销金额为正错误问题
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixRedOtherExpenseAmount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixRedOtherExpenseAmount(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            //获取开了工作流的公司
            corpidList = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.WORKFLOW.getAlias());
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Map<String, Object> param = new HashMap<>();
        param.put("del", BasicConstant.ZERO);
        param.put("updateTimeStart",paymentSheetDataDTO.getUpdateTimeStart());
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
            param.put("corpid", corpid);
            List<OtherExpenseEntity> entitys = otherExpenseModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(entitys)) {
                continue;
            }
            List<UpdateDataEntity> updateList = new ArrayList<>();
            for (OtherExpenseEntity entity : entitys){
                JSONObject jsonObject = new JSONObject();
                JSONObject data = entity.getData();
                String isRed = data.getString(OtherExpenseEnum.SHEET_TYPE_OTHER.getAttr());
                //是否红冲
                boolean red = OtherExpenseSheetTypeEnum.isRed(isRed);
                if (red){
                    double amount = data.getDoubleValue(OtherExpenseEnum.AMOUNT.getAttr());
                    if (amount < 0){
                        continue;
                    }else {
                        amount = -amount;
                    }
                    jsonObject.put(OtherExpenseEnum.AMOUNT.getAttr(),amount);
                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                    updateList.add(updateDataEntity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)){
                otherExpenseModel.updateBatch(updateList,corpid);
            }
        }
        LOG.info("-----------time consume fixRedOtherExpenseAmount:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }


    /**
     * 工作流公司 - 修复回、付款单、其他支出单、资金调拨单的资金账户和金额字段
     * 资金账户流水中支出单据（付款单，其他支出单，资金调拨单流出）存的是 与主表相反的 金额
     * 支出单据（回款单，其他收入单，资金调拨单流入）存的是与主表相等的金额
     * 不支持全量公司刷
     *
     * @param paymentSheetDataDTO
     * @return
     */
    @RequestMapping(value = "/fixPaymentAndPaySheetFundAccount", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPaymentAndPaySheetFundAccount(@RequestBody @Valid PaymentSheetDataDTO paymentSheetDataDTO) throws XbbException{
        if (!proBaseConfig.getXbbCode().equals(paymentSheetDataDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = Objects.isNull(paymentSheetDataDTO.getCorpidList()) ? new ArrayList<>() : paymentSheetDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            //获取开了工作流的公司
            //corpidList = companyConfigModel.getByAliasAllCorpids(CompanyConfigEnum.WORKFLOW.getAlias());
            return "corpidList不能为空";
        }
        long timeStart = DateTimeUtil.getInt();
        LOG.info("总共有多少家需要处理的公司:{}", corpidList.size());
        Integer type = paymentSheetDataDTO.getType();
        Map<String, Object> param = new HashMap<>();
        Map<String, Object> sheetParam = new HashMap<>();
        sheetParam.put("del", BasicConstant.ZERO);
        int pageNum = 500;
        Long idGte = 0L;
        Integer startId = 0;
        param.put("del", BasicConstant.ZERO);
        param.put("type",type);
        param.put("start", startId);
        param.put("pageNum", pageNum);
        param.put("orderByStr", "id asc");
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOG.info("现在是第{}家公司, corpid:{}", i, corpid);
            param.put("corpid", corpid);
            while (true){
                param.put("idGte", idGte);
                List<FundAccountFlowEntity> flowEntityList = fundAccountFlowModel.findEntitys(param);
                if (CollectionsUtil.isEmpty(flowEntityList)) {
                    break;
                }
                LOG.warn("处理进度：已处理到 tb_fund_account_flow.id " + idGte);

                idGte = flowEntityList.get(flowEntityList.size() - 1).getId();

                Map<Long, String> sheetIdToAccountMap = new HashMap<>();
                Map<Long, Double> sheetIdToAmountMap = new HashMap<>();
                List<Long> sheetIdIn = new ArrayList<>();
                for (FundAccountFlowEntity flowEntity : flowEntityList){
                    sheetIdIn.add(flowEntity.getSheetId());
                    sheetIdToAccountMap.put(flowEntity.getSheetId(),flowEntity.getAccountId().toString());
                    sheetIdToAmountMap.put(flowEntity.getSheetId(),flowEntity.getSheetAmount());
                }
                sheetParam.put("idIn",sheetIdIn);
                List<UpdateDataEntity> updateList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(sheetIdIn)){
                    FundAccountFlowTypeEnum flowTypeEnum = FundAccountFlowTypeEnum.getAccountTypeByCode(type);
                    switch (flowTypeEnum){
                        case PAYMENT_SHEET:
                            List<PaymentSheetEntityExt> paymentSheetList = paymentSheetModel.getPaymentSheetByIdIn(corpid, sheetIdIn);
                            for (PaymentSheetEntityExt entity : paymentSheetList){
                                JSONObject data = entity.getData();
                                String sheetType = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                                PaymentSheetTypeEnum paymentSheetTypeEnum = PaymentSheetTypeEnum.getByCode(sheetType);
                                JSONObject jsonObject = new JSONObject();
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(),"");
                                Double flowAmount = sheetIdToAmountMap.getOrDefault(entity.getId(), 0D);
                                String paymentAccount = data.getString(PaymentSheetEnum.FUND_ACCOUNT.getAttr());
                                Double paymentAmount = data.getDouble(PaymentSheetEnum.AMOUNT.getAttr());
                                Double paymentWriteOffAmount = data.getDouble(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr());
                                if(!Objects.equals(flowAccount,paymentAccount)){
                                    jsonObject.put(PaymentSheetEnum.FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                switch (paymentSheetTypeEnum){
                                    case WRITE_OFF:
                                    case RED_WRITE_OFF:
                                    case RED_WRITE_OFF_PREPAYMENT:
                                        if (!Objects.equals(flowAmount,paymentAmount)){
                                            jsonObject.put(PaymentSheetEnum.AMOUNT.getAttr(),flowAmount);
                                        }
                                        if (!Objects.equals(flowAmount,paymentWriteOffAmount)){
                                            jsonObject.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                    case RED_PREPAYMENT:
                                    case PREPAYMENT:
                                        if (!Objects.equals(flowAmount,paymentAmount)){
                                            jsonObject.put(PaymentSheetEnum.AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                    case RED_WRITE_OFF_BALANCE:
                                    case WRITE_OFF_PREPAYMENT:
                                        if (!Objects.equals(flowAmount,paymentWriteOffAmount)){
                                            jsonObject.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                    default:
                                        break;
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                paymentSheetModel.updateBatch(updateList,corpid);
                            }
                            break;
                        case PAY_SHEET:
                            List<PayPlanSheetEntityExt> paySheetList = payPlanSheetModel.getPaySheetByIdIn(corpid, sheetIdIn);
                            for (PayPlanSheetEntityExt entity : paySheetList){
                                JSONObject jsonObject = new JSONObject();
                                JSONObject data = entity.getData();
                                String sheetType = data.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                                PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByCode(sheetType);
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(), "");
                                //付款单的流水金额需要取反
                                Double flowAmount = sheetIdToAmountMap.getOrDefault(entity.getId(), 0D);
                                flowAmount = Arith.mul(flowAmount,-1);
                                String payAccount = data.getString(PaySheetEnum.FUND_ACCOUNT.getAttr());
                                Double payAmount = data.getDouble(PaySheetEnum.AMOUNT.getAttr());
                                Double payWriteOffAmount = data.getDouble(PaySheetEnum.WRITE_OFF_AMOUNT.getAttr());
                                if(!Objects.equals(flowAccount,payAccount)){
                                    jsonObject.put(PaySheetEnum.FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                switch (paySheetTypeEnum){
                                    case WRITE_OFF_PAY:
                                    case RED_WRITE_OFF_PAY:
                                    case RED_WRITE_OFF_PREPAY:
                                        if (!Objects.equals(flowAmount,payAmount)){
                                            jsonObject.put(PaySheetEnum.AMOUNT.getAttr(),flowAmount);
                                        }
                                        if (!Objects.equals(flowAmount,payWriteOffAmount)){
                                            jsonObject.put(PaySheetEnum.WRITE_OFF_AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                    case RED_PREPAY:
                                    case PREPAY:
                                        if (!Objects.equals(flowAmount,payAmount)){
                                            jsonObject.put(PaySheetEnum.AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                    case WRITE_OFF_PREPAY:
                                        if (!Objects.equals(flowAmount,payWriteOffAmount)){
                                            jsonObject.put(PaySheetEnum.WRITE_OFF_AMOUNT.getAttr(),flowAmount);
                                        }
                                        break;
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                payPlanSheetModel.updateBatch(updateList,corpid);
                            }
                            break;
                        case OTHER_EXPENSE:
                            List<OtherExpenseEntity> otherExpenseList = otherExpenseModel.findEntitys(sheetParam);
                            for (OtherExpenseEntity entity : otherExpenseList){
                                JSONObject jsonObject = new JSONObject();
                                JSONObject data = entity.getData();
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(), "");
                                Double flowAmount = sheetIdToAmountMap.getOrDefault(entity.getId(), 0D);
                                //支出单的流水金额需要取反
                                flowAmount = Arith.mul(flowAmount,-1);
                                String expenseAccount = data.getString(OtherExpenseEnum.FUND_ACCOUNT.getAttr());
                                Double expenseAmount = data.getDoubleValue(OtherExpenseEnum.AMOUNT.getAttr());
                                if(!Objects.equals(flowAccount,expenseAccount)){
                                    jsonObject.put(OtherExpenseEnum.FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                if (!Objects.equals(flowAmount,expenseAmount)){
                                    jsonObject.put(OtherExpenseEnum.AMOUNT.getAttr(),flowAmount);
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                otherExpenseModel.updateBatch(updateList,corpid);
                            }
                            break;
                        case OTHER_INCOME:
                            List<OtherIncomeEntity> otherIncomeEntities = otherIncomeModel.findEntitys(sheetParam);
                            for (OtherIncomeEntity entity : otherIncomeEntities){
                                JSONObject jsonObject = new JSONObject();
                                JSONObject data = entity.getData();
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(), "");
                                Double flowAmount = sheetIdToAmountMap.getOrDefault(entity.getId(), 0D);
                                String incomeAccount = data.getString(OtherIncomeEnum.FUND_ACCOUNT.getAttr());
                                Double incomeAmount = data.getDoubleValue(OtherIncomeEnum.AMOUNT.getAttr());
                                if(!Objects.equals(flowAccount,incomeAccount)){
                                    jsonObject.put(OtherIncomeEnum.FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                if (!Objects.equals(flowAmount,incomeAmount)){
                                    jsonObject.put(OtherIncomeEnum.AMOUNT.getAttr(),flowAmount);
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                otherIncomeModel.updateBatch(updateList,corpid);
                            }
                            break;
                        case FUND_TRANSFER_IN:
                            List<FundTransferEntity> fundTransferInList = fundTransferModel.findEntitys(sheetParam);
                            for (FundTransferEntity entity : fundTransferInList){
                                JSONObject jsonObject = new JSONObject();
                                JSONObject data = entity.getData();
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(), "");
                                Double flowAmount = sheetIdToAmountMap.getOrDefault(entity.getId(), 0D);
                                String transferInAccount = data.getString(FundTransferEnum.IN_FUND_ACCOUNT.getAttr());
                                Double transferInAmount = data.getDoubleValue(FundTransferEnum.AMOUNT.getAttr());
                                if(!Objects.equals(flowAccount,transferInAccount)){
                                    jsonObject.put(FundTransferEnum.IN_FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                if (!Objects.equals(transferInAmount,flowAmount)){
                                    jsonObject.put(FundTransferEnum.AMOUNT.getAttr(),flowAmount);
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                fundTransferModel.updateBatch(updateList,corpid);
                            }
                            break;
                        case FUND_TRANSFER_OUT:
                            List<FundTransferEntity> fundTransferOutList = fundTransferModel.findEntitys(sheetParam);
                            for (FundTransferEntity entity : fundTransferOutList){
                                JSONObject jsonObject = new JSONObject();
                                JSONObject data = entity.getData();
                                String flowAccount = sheetIdToAccountMap.getOrDefault(entity.getId(), "");
                                String transferOutAccount = data.getString(FundTransferEnum.OUT_FUND_ACCOUNT.getAttr());
                                if(!Objects.equals(flowAccount,transferOutAccount)){
                                    jsonObject.put(FundTransferEnum.OUT_FUND_ACCOUNT.getAttr(),flowAccount);
                                }
                                if (jsonObject.size() > 0){
                                    UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(entity.getId(), jsonObject, corpid);
                                    updateList.add(updateDataEntity);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateList)){
                                fundTransferModel.updateBatch(updateList,corpid);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }



        }
        LOG.info("-----------time consume fixRedOtherExpenseAmount:" + (DateTimeUtil.getInt() - timeStart));
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }



    public static void main(String[] args) {
        Long connectId = -1L;
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", 1L);
        jsonArray.add(jsonObject);

        connectId = jsonArray.getLong(0);
    }
}
